⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ul_inlib.c

📁 一个linux下rs485驱动程序的源代码
💻 C
字号:
/*******************************************************************  uLan Communication - uL_DRV - multiplatform uLan driver  ul_inlib.c	- interface for driver compiled into library                  linked directly with application  (C) Copyright 1996-2004 by Pavel Pisa - project originator        http://cmp.felk.cvut.cz/~pisa  (C) Copyright 1996-2004 PiKRON Ltd.        http://www.pikron.com  (C) Copyright 2002-2004 Petr Smolik    The uLan driver project can be used and distributed   in compliance with any of next licenses   - GPL - GNU Public License     See file COPYING for details.   - LGPL - Lesser GNU Public License   - MPL - Mozilla Public License   - and other licenses added by project originator  Code can be modified and re-distributed under any combination  of the above listed licenses. If contributor does not agree with  some of the licenses, he/she can delete appropriate line.  WARNING: if you delete all lines, you are not allowed to  distribute code or sources in any form. *******************************************************************//*******************************************************************//* Interface for driver in library *//* needs for UL_DEV_NAME */#include <ul_lib/ul_fddir.h> #define UL_MINORS 4ul_drv *ul_drv_arr[UL_MINORS]={[0 ... UL_MINORS-1]=NULL};void uld_check_timeout(void);ul_drv *uld_try_open_new(const char *dev_name,                         const char *options, int minor);ul_opdata *ul_open(const char *dev_name, const char *options){  ul_drv *udrv;  ul_opdata *opdata;  unsigned int minor;  const char *p;  /*if(dev_name==NULL) { errno=ENODEV; return NULL;} */  if(dev_name==NULL) dev_name=UL_DEV_NAME;  if(!strncasecmp(dev_name,"COM",3)){  /* strnicmp */    p=dev_name+3;    if(*p<'1') { errno=ENODEV; return NULL;}    minor=*p-'1';  }else{ if(!strncmp(dev_name,"/dev/ulan",9)){      p=dev_name+9;    }else {      p=dev_name;    }    if(!*p||(*p==' ')||(*p==':')) minor=0;    else{      if(*p<'0') { errno=ENODEV; return NULL;}      minor=*p-'0';    }  }  if (minor >= UL_MINORS) { errno=ENODEV; return NULL;} #ifndef CONFIG_OC_UL_DRV_SYSLESS  if (!ul_drv_arr[minor]){    ul_drv_arr[minor]=uld_try_open_new(dev_name,options,minor);  } #endif /* CONFIG_OC_UL_DRV_SYSLESS */  if (!ul_drv_arr[minor]){    errno=ENODEV; return NULL;  }  udrv=ul_drv_arr[minor];  if(!(opdata=MALLOC(sizeof(ul_opdata))))  { errno=ENOMEM;    return NULL;  };  memset(opdata,0,sizeof(ul_opdata));  /* opdata->file=file; */  opdata->magic=ULOP_MAGIC;  opdata->message=NULL;  opdata->udrv=udrv;  /* init_waitqueue_head(&opdata->wqrec); */  opdata->opprew=NULL;  opdata->opnext=NULL;  opdata->recchain=NULL;  opdata->filtchain=NULL;  { /* add us onto list of clients of udrv */    ul_opdata *opptr;    UL_DRV_LOCK_FINI    UL_DRV_LOCK;    opptr=udrv->operators;    if(opptr) {opptr->opprew=opdata;opdata->opnext=opptr;};    UL_MB();    udrv->operators=opdata;    UL_DRV_UNLOCK;  };  uld_printk_flush();  return opdata;}int ul_close(ul_opdata* opdata){  ul_opchain *opmember;  if (opdata->message) ulan_freemsg(opdata);  { /* delete us from list of clients of udrv */    ul_drv *udrv=opdata->udrv;    ul_opdata *opptr;    UL_DRV_LOCK_FINI    UL_DRV_LOCK;    if((opptr=opdata->opnext)) opptr->opprew=opdata->opprew;    if((opptr=opdata->opprew)) opptr->opnext=opdata->opnext;    else udrv->operators=opdata->opnext;    UL_DRV_UNLOCK;    if(udrv->irq>0) ul_synchronize_irq(udrv->irq);  };  schedule();  while((opmember=opdata->recchain))  {    del_from_opchain(&opdata->recchain,opmember);    if(opmember->message) ul_dec_ref_cnt(opmember->message);    FREE(opmember);  };  while((opmember=opdata->filtchain))  {    del_from_opchain(&opdata->filtchain,opmember);    FREE(opmember);  };  FREE(opdata);  /* UL_PRINTF("uLan : printudrvbll\n"); */  /* printudrvbll(opdata->udrv); */    uld_printk_flush();  return 0;}ssize_t	ul_read(ul_opdata* opdata, void *buf, size_t count){  int cn;  int len;  if(!opdata->message)  {    errno=ENOMSG;    return -1;  }  if(opdata->data.pos+count>UL_BLK_HEAD(opdata->data.head_blk).len)   count=UL_BLK_HEAD(opdata->data.head_blk).len-opdata->data.pos;  cn=count;  while(cn>0)  {    if(!ul_di_adjust(&opdata->data))    {      memset(buf,0,cn);      cn=0;      break;    };    len=ul_di_atonce(&opdata->data);    if(len>cn) len=cn;    memcpy(buf,ul_di_byte(&opdata->data),len);    ul_di_add(&opdata->data,len);    buf+=len;    cn-=len;  };  return count-cn;};ssize_t	ul_write(ul_opdata* opdata, const void *buf, size_t count){  int cn;  int len;  ul_mem_blk *blk;  if(!opdata->message)  {    errno=ENOMSG;    return -1;  }  cn=count;  while(cn>0)  {    while(!ul_di_adjust(&opdata->data))    {      if(!(blk=ul_alloc_blk(opdata->udrv)))         {count-=cn;cn=0;break;};      memset(UL_BLK_NDATA(blk),0,UL_BLK_SIZE);      opdata->data.blk->next=blk;    };    len=ul_di_atonce(&opdata->data);    if(len>cn) len=cn;    memcpy(ul_di_byte(&opdata->data),buf,len);    ul_di_add(&opdata->data,len);    buf+=len;    cn-=len;  };  if(opdata->data.pos>UL_BLK_HEAD(opdata->data.head_blk).len)    UL_BLK_HEAD(opdata->data.head_blk).len=opdata->data.pos;  return count-cn;};int ul_newmsg(ul_opdata* opdata,const ul_msginfo *msginfo){ int ret;  ret=ulan_newmsg(opdata,msginfo);  if(ret<0) {errno=-ret;ret=-1;}  return ret;}int ul_tailmsg(ul_opdata* opdata,const ul_msginfo *msginfo){ int ret;  ret=ulan_tailmsg(opdata,msginfo);  if(ret<0) {errno=-ret;ret=-1;}  return ret;}int ul_freemsg(ul_opdata* opdata){ int ret;  ret=ulan_freemsg(opdata);  if(ret<0) {errno=-ret;ret=-1;}  return ret;}int ul_acceptmsg(ul_opdata* opdata,ul_msginfo *msginfo){ int ret;  ret=ulan_acceptmsg(opdata,msginfo);  if(ret<0) {errno=-ret;ret=-1;}  return ret;}int ul_actailmsg(ul_opdata* opdata,ul_msginfo *msginfo){ int ret;  ret=ulan_actailmsg(opdata,msginfo);  if(ret<0) {errno=-ret;ret=-1;}  return ret;}int ul_addfilt(ul_opdata* opdata,const ul_msginfo *msginfo){ int ret;  ret=ulan_addfilt(opdata,msginfo);  if(ret<0) {errno=-ret;ret=-1;}  return ret;}int ul_abortmsg(ul_opdata* opdata){ int ret;  ret=ulan_abortmsg(opdata);  if(ret<0) {errno=-ret;ret=-1;}  return ret;}int ul_rewmsg(ul_opdata* opdata){ int ret;  ret=ulan_rewmsg(opdata);  if(ret<0) {errno=-ret;ret=-1;}  return ret;}int ul_inepoll(ul_opdata* opdata){ int ret; #if 1 /* Processing of arrived or processed messages */  uld_check_timeout();  if(uld_test_dfl(opdata->udrv,ASK_BOTTOM))  {    ulan_do_bh(opdata->udrv);  } #endif  ret=ulan_inepoll(opdata);  uld_printk_flush();  if(ret<0) {errno=-ret;ret=-1;}  return ret;}int ul_stroke(ul_opdata* opdata){  ul_drv *udrv;  if(!opdata->udrv) return -ENODEV;  udrv=opdata->udrv;  ulan_stroke(udrv, 1);  return 0;}int ul_hwtest(ul_opdata* opdata, unsigned int fnc){ int ret;  ret=ulan_hwtest(opdata,fnc);  if(ret<0) {errno=EINVAL;ret=-1;}  return ret;}int ul_setmyadr(ul_opdata* opdata, int newadr){  int ret;  ret=ulan_setmyadr(opdata, newadr);  if(ret<0) {errno=-ret;ret=-1;}  return ret;}int ul_setidstr(ul_opdata* opdata, const char *idstr){  int ret;  ret=ulan_setidstr(opdata, idstr);  if(ret<0) {errno=-ret;ret=-1;}  return ret;}int ul_setbaudrate(ul_opdata* opdata, int baudrate){  int ret;  ret=ulan_setbaudrate(opdata, baudrate);  if(ret<0) {errno=-ret;ret=-1;}  return ret;}int ul_drv_debflg(ul_opdata* opdata,int debug_msk)  {uld_debug_flg=debug_msk;return uld_debug_flg;};#ifdef UL_LOG_ENABLE#include <stdarg.h>#define ULD_PRINTK_BUF_LEN 4096char uld_printk_buf[ULD_PRINTK_BUF_LEN];char *uld_printk_pin=uld_printk_buf;char *uld_printk_pout=uld_printk_buf;int uld_printk(const char *format, ...){  int len,rest,ret;  char buf[255];  va_list va=0;  UL_IRQ_LOCK_FINI  if(uld_debug_flg&LOG_MSK_DISABLE) return 0;  va_start(va,format);  ret=vsprintf(buf,format,va);  va_end(va);  len=strlen(buf);  UL_IRQ_LOCK;  rest=uld_printk_buf+ULD_PRINTK_BUF_LEN-uld_printk_pin;  if(len>=rest){    memcpy(uld_printk_pin,buf,rest); len-=rest;    memcpy(uld_printk_buf,buf,len);    uld_printk_pin=uld_printk_buf+len;  }else{    memcpy(uld_printk_pin,buf,len); uld_printk_pin+=len;  }  UL_IRQ_UNLOCK;  return ret;}void uld_printk_flush(void){  char *pout,*pin;  UL_IRQ_LOCK_FINI  UL_IRQ_LOCK;  pin=uld_printk_pin;  pout=uld_printk_pout;  UL_IRQ_UNLOCK;  if(pin==pout) return;  if(pin>pout){    fwrite(pout,pin-pout,1,stderr); uld_printk_pout=pin;  }else{    fwrite(pout,uld_printk_buf+ULD_PRINTK_BUF_LEN-pout,1,stderr);    fwrite(uld_printk_buf,pin-uld_printk_buf,1,stderr);    uld_printk_pout=pin;  }  fflush(stderr);}#endif /* UL_LOG_ENABLE */void uld_check_timeout(void){  int i;  ul_drv *udrv; #ifdef JIFFIES_FROM_GETTIMEOFDAY  struct timeval actual;  long int new_expires;  static long int old_expires; #endif /* JIFFIES_FROM_GETTIMEOFDAY */ #ifdef __DJGPP__  UL_DRV_LOCK_FINI #endif /* __DJGPP__ */ #ifdef JIFFIES_FROM_GETTIMEOFDAY  gettimeofday(&actual,NULL);  uld_jiffies=actual.tv_usec+actual.tv_sec*ULD_HZ; #endif /* JIFFIES_FROM_GETTIMEOFDAY */  for(i=0;i<UL_MINORS;i++)  {    if((udrv=ul_drv_arr[i])!=NULL)    {      if(uld_test_dfl(udrv,WDSCHED))      {        #ifdef JIFFIES_FROM_GETTIMEOFDAY        if(old_expires!=udrv->wd_timer_expires)        { UL_DRV_LOCK;          new_expires=uld_jiffies+ULD_HZ/18;          if((new_expires-udrv->wd_timer_expires)<0)            new_expires=udrv->wd_timer_expires;          old_expires=udrv->wd_timer_expires=new_expires;          UL_DRV_UNLOCK;          LOG_IRQ("sched timeout %ld at time %ld\n",new_expires,uld_jiffies);        }       #elif 1        { static long int old_expires;          if(old_expires!=udrv->wd_timer_expires)            LOG_IRQ("sched timeout %ld at time %ld\n",                    old_expires=udrv->wd_timer_expires,jiffies);        }       #endif /* JIFFIES_FROM_GETTIMEOFDAY */        if((udrv->wd_timer_expires-jiffies)<0)        { uld_clear_dfl(udrv,WDSCHED);          ulan_do_wd_timer((unsigned long)udrv);          /* uld_timeout(udrv); */          /* printudrvfncstack(udrv) */        }      }      /* Call bottom halves as needed */      if(uld_test_dfl(udrv,ASK_BOTTOM))      {        uld_clear_dfl(udrv,ASK_BOTTOM);        ulan_do_bh(udrv);      }    }  } #ifdef __DJGPP__  #if 1  __save_flags(ul_irq_lock_flags);  if(!(ul_irq_lock_flags&0x0200))  { LOG_FATAL(KERN_CRIT "Somebody disables IRQ !!!!!\n");    __sti();  }  #endif  __dpmi_yield(); #endif}#ifndef CONFIG_OC_UL_DRV_SYSLESStypedef struct uld_dev_params{  int  port;  int  irq;  int  baud;  int  my_adr;  long baudbase;}uld_dev_params_t;static const uld_dev_params_t  uld_dev_params_defaults[4]={    {0x3f8,0x4,19200,2,0},    {0x2f8,0x3,19200,2,0},    {0x3e8,0x5,19200,2,0},    {0x2e8,0x5,19200,2,0}  };ul_drv *uld_try_open_new(const char *dev_name,                         const char *options, int minor){  uld_dev_params_t params;  const char *p,*r;  char *s;  char chip_name[16];  if(minor<4) params=uld_dev_params_defaults[minor];  else  params=uld_dev_params_defaults[0];  chip_name[0]=0;  p=dev_name;  while(*p){    while(*p&&(*p!=' ')&&(*p!=':')) p++;    while(*p&&((*p==' ')||(*p==':'))) p++;    r=p;    while(*r&&(*r!=' ')&&(*r!=':')&&((*r<'0')||(*r>'9'))) r++;    switch (*p) {      case 'p': params.port=strtol(r,NULL,0); break;      case 'i': params.irq=strtol(r,NULL,0); break;      case 'b': params.baud=strtol(r,NULL,0); break;      case 'a': params.my_adr=strtol(r,NULL,0); break;      case 'c': for(s=chip_name,p++;*p&&(*p!=':');p++,s++)                   *s=*p;		*s=0;                break;    }  }  /* printf("port %d irq %d baud %d my_adr %d\n",    params.port,params.irq,params.baud,params.my_adr);  return NULL; */  return ul_drv_new(params.port,params.irq,params.baud,params.my_adr,  		    chip_name[0]?chip_name:NULL,params.baudbase);}#else /* CONFIG_OC_UL_DRV_SYSLESS */int ul_drv_add_dev(ul_drv *udrv) {  int minor;  for(minor=0;minor<UL_MINORS;minor++) {    if (ul_drv_arr[minor]==NULL) {      ul_drv_arr[minor]=udrv;      return 0;    }  }  return -1;}#endif /* CONFIG_OC_UL_DRV_SYSLESS */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -