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

📄 eibdrv.c

📁 欧洲安装总线系统的USB串口接口驱动c程序源代码.软件代码由西门子公司提供
💻 C
📖 第 1 页 / 共 5 页
字号:
   if (ftstation.port.filp->f_op->read(ftstation.port.inodp,ftstation.port.filp,buf,1)==0)#endif      return -EAGAIN;      return 1;}      int timeout_read(unsigned char *buf,int count){  int n_read=0;   int result;   struct termios help_termios;   ftstation.port.tty->termios->c_cc[VTIME]=1;   ftstation.port.tty->termios->c_cc[VMIN]=0;   ftstation.port.tty->driver.set_termios(ftstation.port.tty,&help_termios);   ftstation.port.tty->ldisc.set_termios(ftstation.port.tty,&help_termios);   while (n_read<count)   {  #if LINUX_VERSION_CODE >= VERSION_CODE(2,1,0)            if  ((result=ftstation.port.filp->f_op->read(ftstation.port.filp,buf+n_read,                  count-n_read,&ftstation.port.filp->f_pos))==0)#else      if ((result=ftstation.port.filp->f_op->read(ftstation.port.inodp,ftstation.port.filp,&buf[n_read],                  count-n_read))==0)            #endif      {  ftstation.port.tty->termios->c_cc[VTIME]=0;         ftstation.port.tty->termios->c_cc[VMIN]=0;         ftstation.port.tty->driver.set_termios(ftstation.port.tty,&help_termios);         ftstation.port.tty->ldisc.set_termios(ftstation.port.tty,&help_termios);         return n_read;      }      n_read+=result;   }   ftstation.port.tty->termios->c_cc[VTIME]=0;   ftstation.port.tty->termios->c_cc[VMIN]=0;   ftstation.port.tty->driver.set_termios(ftstation.port.tty,&help_termios);   ftstation.port.tty->ldisc.set_termios(ftstation.port.tty,&help_termios);   return n_read;}int repeat_write(unsigned char *msg,int msg_len,int wait_state){  unsigned char ack_msg[4];   int stat_write=0;   struct timeval wait_start,wait_actual;   unsigned long wait_jiffies;      ftstation.wrepeat=0;   ftstation.state=wait_state;   if (wait_state==FT_STATE_WAIT_FOR_UDATA_ACK)      stat_write=1;         fs=get_fs();   set_fs(KERNEL_DS);            do   {  ftstation.wrepeat++;#ifdef DEBUG            printk(KERN_WARNING "eibdrv (%i): Schreibversuch %i\n",c++,ftstation.wrepeat);#endif            line_idle_delay();      do_gettimeofday(&ftstation.start_write);#if LINUX_VERSION_CODE >= VERSION_CODE(2,1,0)            ftstation.port.filp->f_op->write(ftstation.port.filp,msg,msg_len,&ftstation.port.filp->f_pos);#else      ftstation.port.filp->f_op->write(ftstation.port.inodp,ftstation.port.filp,msg,msg_len);#endif                  do_gettimeofday(&ftstation.last_seract);      switch(mode)      {  case FT_SERVERMODE:                 unlock(&sv_ser_read);#if LINUX_VERSION_CODE >= VERSION_CODE(2,1,0)                 interruptible_sleep_on_timeout(&wq_wait_for_ack,ftstation.exchange_timeout);      #else                 current->timeout=jiffies+ftstation.exchange_timeout;                 interruptible_sleep_on(&wq_wait_for_ack);#endif                          lock(&sv_ser_read);                 break;         case FT_STANDARDMODE:                 wait_start=ftstation.last_seract;                 wait_actual=wait_start;                 while (((wait_jiffies=timeval_to_jiffies(diff_timeval(ftstation.exchange_time,                           diff_timeval(wait_actual,wait_start))))>0)&&(ftstation.state!=FT_STATE_READY))                 {#if LINUX_VERSION_CODE >= VERSION_CODE(2,1,0)                    interruptible_sleep_on_timeout(&ftstation.port.tty->read_wait,wait_jiffies);#else                    current->timeout=jiffies+wait_jiffies;                    interruptible_sleep_on(&ftstation.port.tty->read_wait);#endif                             do_gettimeofday(&wait_actual);                    while ((immediate_read(&ack_msg[0])==1)&&(ftstation.state!=FT_STATE_READY))                    {  switch(ack_msg[0])                       {  case FT_FIXED_LENGTH_MSG:                                  if (timeout_read(&ack_msg[0],3)!=3) break;                                  if ((ack_msg[0]!=ack_msg[1])||(ack_msg[2]!=0x16)) break;                                  if ((ack_msg[0]&0xDF)==(0x0B|((1-FT_DIR)<<7)))                                  {  #ifdef DEBUG                                                                          printk(KERN_WARNING "eibdrv (%i): RESP_STATUS  ==>  erhalten\n",c++);#endif                                     if (ftstation.state==FT_STATE_WAIT_FOR_RESP_STATUS)                                        ftstation.state=FT_STATE_READY;                                  }                                  break;                          case FT_ACK:                                  do_gettimeofday(&ftstation.end_write);                                  if (ftstation.wrepeat==1)                                     ftstation.stat.total_w1time=sum_timeval(ftstation.stat.total_w1time,                                            diff_timeval(ftstation.end_write,ftstation.start_write));#ifdef DEBUG                                                                              printk(KERN_WARNING "eibdrv (%i): ACK  ==>  erhalten!\n",c++);#endif                                                                    if ((ftstation.state==FT_STATE_WAIT_FOR_UDATA_ACK)||                                      (ftstation.state==FT_STATE_WAIT_FOR_RESET_ACK))                                     ftstation.state=FT_STATE_READY;                                  break;                       }                    }                    break;                 }      }   }   while ((ftstation.state==wait_state)&&(ftstation.wrepeat<FT_REPEAT_LIMIT));   set_fs(fs);            if (ftstation.state==wait_state)   {  ftstation.state=FT_STATE_READY;      if (stat_write==1)      {  if (ftstation.stat.write[0]<ULONG_MAX)            ftstation.stat.write[0]++;         else            ftstation.stat.overflow=1;      }      return 0;   }   else   {  if (stat_write==1)      {  if (ftstation.stat.write[ftstation.wrepeat]<ULONG_MAX)            ftstation.stat.write[ftstation.wrepeat]++;         else            ftstation.stat.overflow=1;      }      return msg_len;   }}void ser_write(void){  int udata_len;   int msg_len;   int checksum;   int i,result;   unsigned char msg[EIB_BUF_ELEMENT_SIZE+7];   do   {  interruptible_sleep_on(&wq_ser_write);//    interruptible_sleep_on_timeout(&sleep_queue,20*HZ);      lock(&sv_ser_write);      lock(&sv_ser_read);            do      {  if ((udata_len=eib_read_buf(ftstation.outbuf,&msg[5]))==0)         {  unlock(&sv_ser_read);            unlock(&sv_ser_write);            break;         }         msg_len=udata_len+7;         msg[0]=msg[3]=0x68;         msg[1]=msg[2]=(unsigned char)(udata_len+1);         msg[4]=(FT_DIR<<7) | 0x40 | (ftstation.fcb<<5) | (FT_FCB_VALID<<4) | 0x03;         checksum=msg[4];#ifdef DEBUG                  printk("<1>Gesendetes fcb=%i\n",ftstation.fcb);#endif DEBUG                  for (i=0;i<udata_len;i++)         {   checksum+=msg[i+5];         }         msg[5+udata_len]=(unsigned char) checksum % 256;         msg[6+udata_len]=0x16;                if ((result=repeat_write(&msg[0],msg_len,FT_STATE_WAIT_FOR_UDATA_ACK))==msg_len)            result=udata_len;         if (result>=1)            ftstation.fcb=1-ftstation.fcb;         eib_result_wpbuf(ftstation.wpbuf,result);         wake_up_interruptible(&wq_wproc);      }      while(1);   }   while (ftstation.state!=FT_STATE_SHUTDOWN);}int ser_reset(void){  int result=0;   unsigned char msg[4];      msg[0]=0x10;   msg[1]=msg[2]=(0x40 | (FT_DIR << 7));   msg[3]=0x16;   lock(&sv_ser_write);   lock(&sv_ser_read);      if (repeat_write(&msg[0],4,FT_STATE_WAIT_FOR_RESET_ACK)==0)      result=-ENORESET;   unlock(&sv_ser_read);   unlock(&sv_ser_write);            return result;}int ser_status(void){  int result=0;   unsigned char msg[4];      msg[0]=0x10;   msg[1]=msg[2]=(0x49 | (FT_DIR << 7));   msg[3]=0x16;   lock(&sv_ser_write);   lock(&sv_ser_read);   if (repeat_write(&msg[0],4,FT_STATE_WAIT_FOR_RESP_STATUS)==0)      result=-ENORESPSTATUS;   unlock(&sv_ser_read);   unlock(&sv_ser_write);               return result;}void empty_ttyS() {  unsigned char msg;   struct termios help_termios;      ftstation.port.tty->termios->c_cc[VTIME]=0;   ftstation.port.tty->termios->c_cc[VMIN]=0;             ftstation.port.tty->driver.set_termios(ftstation.port.tty,&help_termios);   ftstation.port.tty->ldisc.set_termios(ftstation.port.tty,&help_termios);   while (ftstation.port.filp->f_op->read(ftstation.port.filp,&msg,1,&ftstation.port.filp->f_pos)!=0)      ;      ftstation.port.tty->termios->c_cc[VTIME]=1;   ftstation.port.tty->termios->c_cc[VMIN]=0;             ftstation.port.tty->driver.set_termios(ftstation.port.tty,&help_termios);   ftstation.port.tty->ldisc.set_termios(ftstation.port.tty,&help_termios);}         void ser_read(void){  int checksum;   int msg_fcb;   int i,k=0;   int udata_len;   unsigned char msg[EIB_BUF_ELEMENT_SIZE+7];      do   {  k++;      interruptible_sleep_on(&ftstation.port.tty->read_wait);      if (ftstation.state==FT_STATE_SHUTDOWN)         break;      fs=get_fs();      set_fs(KERNEL_DS);       //    if (timeout_read(&msg[0],1)==1)      while (immediate_read(&msg[0])==1)            {  do_gettimeofday(&ftstation.end_write);                           switch(msg[0])         {  case FT_VAR_LENGTH_MSG: // SEND_UDATA received                    if (timeout_read(&msg[0],4)!=4) break;                    if ((msg[0]!=msg[1]) || (msg[0]>24) || (msg[2]!=0x68) ||                       ((msg[3]&0xDF)!=(unsigned char)(((1-FT_DIR)<<7) | 0x40 | (FT_FCB_VALID<<4) | 0x03)))                       break;                    msg_fcb=(int)((msg[3] & 0x20)>>5);                    checksum=msg[3];                    udata_len=msg[0]-1;                    if (timeout_read(&msg[0],udata_len+2)!=udata_len+2) break;                    for (i=0;i<udata_len;i++)                       checksum+=msg[i];                    if ((msg[udata_len]!=(unsigned char)(checksum%256)) || (msg[udata_len+1]!=0x16))                       break;                    if (msg_fcb==(1-ftstation.rec_fcb))   // msg not already received                    {  #ifdef DEBUG                                              printk(KERN_WARNING "eibdrv (%i): SEND_UDATA  ==>  neue Nachricht\n",c++);                       printk("<1>fcb erwartet = %i     erhalten = %i\n",(1-ftstation.rec_fcb),msg_fcb); #endif                                              ftstation.rec_fcb=1-ftstation.rec_fcb;                       ftstation.rrepeat=0;                       eib_wmsg_rpbuf(ftstation.rpbuf,&msg[0],udata_len);                       wake_up_interruptible(&wq_rproc);                       if (ftstation.pasync!=NULL)                          kill_fasync(ftstation.pasync,SIGIO);                    }                    else                     {  #ifdef DEBUG                                              printk(KERN_WARNING "eibdrv (%i): SEND_UDATA  ==>  bereits erhalten\n",c++);                       printk("<1>fcb erwartet = %i     erhalten = %i\n",(1-ftstation.rec_fcb),msg_fcb); #endif                                              if (ftstation.rrepeat!=-1)                          ftstation.rrepeat++;                    }                                        if (ftstation.rrepeat<3)                    {  if (ftstation.stat.read[ftstation.rrepeat]<ULONG_MAX)                          ftstation.stat.read[ftstation.rrepeat]++;                       else                          ftstation.stat.overflow=1;                       if (ftstation.rrepeat>0)                          ftstation.stat.read[ftstation.rrepeat-1]--;                      }                    line_idle_delay();                    msg[0]=FT_ACK;#if LINUX_VERSION_CODE >= VERSION_CODE(2,1,0)                                        ftstation.port.filp->f_op->write(ftstation.port.filp,&msg[0],1,&ftstation.port.filp->f_pos);#else                    ftstation.port.filp->f_op->write(ftstation.port.inodp,ftstation.port.filp,&msg[0],1);#endif                                        do_gettimeofday(&ftstation.last_seract);                    break;                                case FT_FIXED_LENGTH_MSG:                    if (timeout_read(&msg[0],3)!=3) break;                    if ((msg[0]!=msg[1]) || (msg[2]!=0x16)) break;                    switch(msg[0] & 0xDF)                    {  case (0x40 | ((1-FT_DIR)<<7)): // SEND_RESET#ifdef DEBUG                                                      printk(KERN_WARNING "eibdrv (%i): SEND_RESET  ==>  erhalten!\n",c++);#endif                                                              ftstation.fcb=1;                               ftstation.rec_fcb=0;                               ftstation.wrepeat=FT_REPEAT_LIMIT;                               line_idle_delay();                               msg[0]=FT_ACK;#if LINUX_VERSION_CODE >= VERSION_CODE(2,1,0)                                                              ftstation.port.filp->f_op->write(ftstation.port.filp,&msg[0],1,                                  &ftstation.port.filp->f_pos);#else                               ftstation.port.filp->f_op->write(ftstation.port.inodp,ftstation.port.filp,&msg[0],1);#endif                                                                                                   do_gettimeofday(&ftstation.last_seract);                               break;                       case (0x49 | ((1-FT_DIR)<<7)): // REQ_STATUS#ifdef DEBUG                                                      printk(KERN_WARNING "eibdrv (%i): REQ_STATUS  ==>  erhalten!\n",c++);#endif DEBUG                                                              line_idle_delay();                               msg[0]=0x10;                               msg[1]=msg[2]=(0x0B | (FT_DIR<<7));                               msg[3]=0x16;#if LINUX_VERSION_CODE >= VERSION_CODE(2,1,0)                                                              ftstation.port.filp->f_op->write(ftstation.port.filp,&msg[0],4,                                  &ftstation.port.filp->f_pos);#else                               ftstation.port.filp->f_op->write(ftstation.port.inodp,ftstation.port.filp,&msg[0],4);#endif                                                                                                   do_gettimeofday(&ftstation.last_seract);                               break;                       case (0x0B | ((1-FT_DIR)<<7)): // RESP_STATUS#ifdef DEBUG                                                       printk(KERN_WARNING "eibdrv (%i): RESP_STATUS  ==>  erhalten!\n",c++);#endif                                                              if (ftstation.state==FT_STATE_WAIT_FOR_RESP_STATUS)                                  ftstation.state=FT_STATE_READY;                               break;                    }                    break;                                      case FT_ACK:            // ACK received                     if (ftstation.wrepeat==1)                       ftstation.stat.total_w1time=sum_timeval(ftstation.stat.total_w1time,                                 diff_timeval(ftstation.end_write,ftstation.start_write));#ifdef DEBUG                                                     printk(KERN_WARNING "eibdrv (%i): ACK  ==>  erhalten\n",c++);#endif                                        if ((ftstation.state==FT_STATE_WAIT_FOR_UDATA_ACK) ||                        (ftstation.state==FT_STATE_WAIT_FOR_RESET_ACK))                       ftstation.state=FT_STATE_READY;                    break;         }  //       empty_ttyS();         if ((ftstation.state==FT_STATE_WAIT_FOR_UDATA_ACK) ||

⌨️ 快捷键说明

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