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

📄 n_r3964.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 3 页
字号:
      restore_flags(flags);   }}static void retry_transmit(struct r3964_info *pInfo){   if(pInfo->nRetry<R3964_MAX_RETRIES)   {      TRACE_PE("transmission failed. Retry #%d",              pInfo->nRetry);      pInfo->bcc = 0;      put_char(pInfo, STX);      flush(pInfo);      pInfo->state = R3964_TX_REQUEST;      pInfo->count_down = R3964_TO_QVZ;      pInfo->nRetry++;   }   else   {      TRACE_PE("transmission failed after %d retries",              R3964_MAX_RETRIES);      remove_from_tx_queue(pInfo, R3964_TX_FAIL);            put_char(pInfo, NAK);      flush(pInfo);      pInfo->state = R3964_IDLE;      trigger_transmit(pInfo);   }}static void transmit_block(struct r3964_info *pInfo){   struct tty_struct *tty = pInfo->tty;   struct r3964_block_header *pBlock = pInfo->tx_first;   int room=0;   if((tty==NULL) || (pBlock==NULL))   {      return;   }   if(tty->driver.write_room)      room=tty->driver.write_room(tty);   TRACE_PS("transmit_block %x, room %d, length %d",           (int)pBlock, room, pBlock->length);      while(pInfo->tx_position < pBlock->length)   {      if(room<2)         break;       if(pBlock->data[pInfo->tx_position]==DLE)      {         /* send additional DLE char: */         put_char(pInfo, DLE);      }      put_char(pInfo, pBlock->data[pInfo->tx_position++]);            room--;   }   if((pInfo->tx_position == pBlock->length) && (room>=3))   {      put_char(pInfo, DLE);      put_char(pInfo, ETX);      if(pInfo->flags & R3964_BCC)      {         put_char(pInfo, pInfo->bcc);      }      pInfo->state = R3964_WAIT_FOR_TX_ACK;      pInfo->count_down = R3964_TO_QVZ;   }   flush(pInfo);}static void on_receive_block(struct r3964_info *pInfo){   unsigned int length;   struct r3964_client_info *pClient;   struct r3964_block_header *pBlock;      length=pInfo->rx_position;   /* compare byte checksum characters: */   if(pInfo->flags & R3964_BCC)   {      if(pInfo->bcc!=pInfo->last_rx)      {         TRACE_PE("checksum error - got %x but expected %x",                pInfo->last_rx, pInfo->bcc);         pInfo->flags |= R3964_CHECKSUM;      }   }   /* check for errors (parity, overrun,...): */   if(pInfo->flags & R3964_ERROR)   {      TRACE_PE("on_receive_block - transmission failed error %x",             pInfo->flags & R3964_ERROR);            put_char(pInfo, NAK);      flush(pInfo);      if(pInfo->nRetry<R3964_MAX_RETRIES)      {         pInfo->state=R3964_WAIT_FOR_RX_REPEAT;         pInfo->count_down = R3964_TO_RX_PANIC;         pInfo->nRetry++;      }      else      {         TRACE_PE("on_receive_block - failed after max retries");         pInfo->state=R3964_IDLE;      }      return;   }      /* received block; submit DLE: */   put_char(pInfo, DLE);   flush(pInfo);   pInfo->count_down=0;   TRACE_PS(" rx success: got %d chars", length);   /* prepare struct r3964_block_header: */   pBlock = kmalloc(length+sizeof(struct r3964_block_header), GFP_KERNEL);   TRACE_M("on_receive_block - kmalloc %x",(int)pBlock);   if(pBlock==NULL)      return;   pBlock->length = length;   pBlock->data   = ((unsigned char*)pBlock)+sizeof(struct r3964_block_header);   pBlock->locks  = 0;   pBlock->next   = NULL;   pBlock->owner  = NULL;   memcpy(pBlock->data, pInfo->rx_buf, length);   /* queue block into rx_queue: */   add_rx_queue(pInfo, pBlock);   /* notify attached client processes: */   for(pClient=pInfo->firstClient; pClient; pClient=pClient->next)   {      if(pClient->sig_flags & R3964_SIG_DATA)      {         add_msg(pClient, R3964_MSG_DATA, length, R3964_OK, pBlock);      }   }   wake_up_interruptible (&pInfo->read_wait);      pInfo->state = R3964_IDLE;   trigger_transmit(pInfo);}static void receive_char(struct r3964_info *pInfo, const unsigned char c){   switch(pInfo->state)   {      case R3964_TX_REQUEST:         if(c==DLE)         {            TRACE_PS("TX_REQUEST - got DLE");            pInfo->state = R3964_TRANSMITTING;            pInfo->tx_position = 0;                        transmit_block(pInfo);         }         else if(c==STX)         {            if(pInfo->nRetry==0)            {               TRACE_PE("TX_REQUEST - init conflict");               if(pInfo->priority == R3964_SLAVE)               {                  goto start_receiving;               }            }             else             {               TRACE_PE("TX_REQUEST - secondary init conflict!?"                        " Switching to SLAVE mode for next rx.");               goto start_receiving;            }         }         else         {            TRACE_PE("TX_REQUEST - char != DLE: %x", c);            retry_transmit(pInfo);         }         break;      case R3964_TRANSMITTING:         if(c==NAK)         {            TRACE_PE("TRANSMITTING - got NAK");            retry_transmit(pInfo);         }         else         {            TRACE_PE("TRANSMITTING - got illegal char");             pInfo->state = R3964_WAIT_ZVZ_BEFORE_TX_RETRY;            pInfo->count_down = R3964_TO_ZVZ;         }         break;      case R3964_WAIT_FOR_TX_ACK:         if(c==DLE)         {            TRACE_PS("WAIT_FOR_TX_ACK - got DLE");            remove_from_tx_queue(pInfo, R3964_OK);                        pInfo->state = R3964_IDLE;            trigger_transmit(pInfo);         }         else         {            retry_transmit(pInfo);         }         break;      case R3964_WAIT_FOR_RX_REPEAT:         /* FALLTROUGH */      case R3964_IDLE:         if(c==STX)         {            /* Prevent rx_queue from overflow: */            if(pInfo->blocks_in_rx_queue >= R3964_MAX_BLOCKS_IN_RX_QUEUE)            {               TRACE_PE("IDLE - got STX but no space in rx_queue!");               pInfo->state=R3964_WAIT_FOR_RX_BUF;               pInfo->count_down = R3964_TO_NO_BUF;               break;            }start_receiving:            /* Ok, start receiving: */            TRACE_PS("IDLE - got STX");            pInfo->rx_position = 0;            pInfo->last_rx = 0;            pInfo->flags &= ~R3964_ERROR;            pInfo->state=R3964_RECEIVING;            pInfo->count_down = R3964_TO_ZVZ;            pInfo->nRetry = 0;            put_char(pInfo, DLE);            flush(pInfo);            pInfo->bcc = 0;         }         break;      case R3964_RECEIVING:         if(pInfo->rx_position < RX_BUF_SIZE)         {            pInfo->bcc ^= c;                        if(c==DLE)            {               if(pInfo->last_rx==DLE)               {                  pInfo->last_rx = 0;                  goto char_to_buf;               }               pInfo->last_rx = DLE;               break;            }             else if((c==ETX) && (pInfo->last_rx==DLE))            {               if(pInfo->flags & R3964_BCC)               {                  pInfo->state = R3964_WAIT_FOR_BCC;                  pInfo->count_down = R3964_TO_ZVZ;               }               else                {                  on_receive_block(pInfo);               }            }            else            {               pInfo->last_rx = c;char_to_buf:               pInfo->rx_buf[pInfo->rx_position++] = c;               pInfo->count_down = R3964_TO_ZVZ;            }         }        /* else: overflow-msg? BUF_SIZE>MTU; should not happen? */          break;      case R3964_WAIT_FOR_BCC:         pInfo->last_rx = c;         on_receive_block(pInfo);         break;   }}static void receive_error(struct r3964_info *pInfo, const char flag){    switch (flag)     {    case TTY_NORMAL:        break;    case TTY_BREAK:        TRACE_PE("received break")        pInfo->flags |= R3964_BREAK;        break;    case TTY_PARITY:        TRACE_PE("parity error")        pInfo->flags |= R3964_PARITY;        break;    case TTY_FRAME:        TRACE_PE("frame error")        pInfo->flags |= R3964_FRAME;        break;    case TTY_OVERRUN:        TRACE_PE("frame overrun")        pInfo->flags |= R3964_OVERRUN;        break;    default:        TRACE_PE("receive_error - unknown flag %d", flag);        pInfo->flags |= R3964_UNKNOWN;        break;    }}static void on_timeout(struct r3964_info *pInfo){   switch(pInfo->state)   {      case R3964_TX_REQUEST:         TRACE_PE("TX_REQUEST - timeout");         retry_transmit(pInfo);         break;      case R3964_WAIT_ZVZ_BEFORE_TX_RETRY:         put_char(pInfo, NAK);         flush(pInfo);         retry_transmit(pInfo);         break;      case R3964_WAIT_FOR_TX_ACK:         TRACE_PE("WAIT_FOR_TX_ACK - timeout");         retry_transmit(pInfo);         break;      case R3964_WAIT_FOR_RX_BUF:         TRACE_PE("WAIT_FOR_RX_BUF - timeout");         put_char(pInfo, NAK);         flush(pInfo);         pInfo->state=R3964_IDLE;         break;      case R3964_RECEIVING:         TRACE_PE("RECEIVING - timeout after %d chars",                   pInfo->rx_position);         put_char(pInfo, NAK);         flush(pInfo);         pInfo->state=R3964_IDLE;         break;      case R3964_WAIT_FOR_RX_REPEAT:         TRACE_PE("WAIT_FOR_RX_REPEAT - timeout");         pInfo->state=R3964_IDLE;         break;      case R3964_WAIT_FOR_BCC:         TRACE_PE("WAIT_FOR_BCC - timeout");         put_char(pInfo, NAK);         flush(pInfo);         pInfo->state=R3964_IDLE;         break;   }}static struct r3964_client_info *findClient(  struct r3964_info *pInfo, pid_t pid){   struct r3964_client_info *pClient;      for(pClient=pInfo->firstClient; pClient; pClient=pClient->next)   {      if(pClient->pid == pid)      {         return pClient;      }   }   return NULL;}static int enable_signals(struct r3964_info *pInfo, pid_t pid, int arg){   struct r3964_client_info *pClient;   struct r3964_client_info **ppClient;   struct r3964_message *pMsg;      if((arg & R3964_SIG_ALL)==0)   {      /* Remove client from client list */      for(ppClient=&pInfo->firstClient; *ppClient; ppClient=&(*ppClient)->next)      {         pClient = *ppClient;                  if(pClient->pid == pid)         {            TRACE_PS("removing client %d from client list", pid);            *ppClient = pClient->next;            while(pClient->msg_count)            {               pMsg=remove_msg(pInfo, pClient);               if(pMsg)               {                  kfree(pMsg);                  TRACE_M("enable_signals - msg kfree %x",(int)pMsg);               }            }            kfree(pClient);            TRACE_M("enable_signals - kfree %x",(int)pClient);            return 0;         }      }      return -EINVAL;   }   else   {      pClient=findClient(pInfo, pid);      if(pClient)      {         /* update signal options */         pClient->sig_flags=arg;      }       else       {         /* add client to client list */         pClient=kmalloc(sizeof(struct r3964_client_info), GFP_KERNEL);         TRACE_M("enable_signals - kmalloc %x",(int)pClient);         if(pClient==NULL)            return -ENOMEM;         TRACE_PS("add client %d to client list", pid);         pClient->sig_flags=arg;         pClient->pid = pid;         pClient->next=pInfo->firstClient;         pClient->first_msg = NULL;         pClient->last_msg = NULL;         pClient->next_block_to_read = NULL;         pClient->msg_count = 0;         pInfo->firstClient=pClient;      }   }   return 0;}static int read_telegram(struct r3964_info *pInfo, pid_t pid, unsigned char *buf){    struct r3964_client_info *pClient;    struct r3964_block_header *block;    if(!buf)    {        return -EINVAL;    }    pClient=findClient(pInfo,pid);    if(pClient==NULL)    {       return -EINVAL;    }        block=pClient->next_block_to_read;    if(!block)    {       return 0;    }    else    {      if (copy_to_user (buf, block->data, block->length))	return -EFAULT;       remove_client_block(pInfo, pClient);       return block->length;    }    return -EINVAL;}static void add_msg(struct r3964_client_info *pClient, int msg_id, int arg,             int error_code, struct r3964_block_header *pBlock){   struct r3964_message *pMsg;   unsigned long flags;      if(pClient->msg_count<R3964_MAX_MSG_COUNT-1)   {queue_the_message:      pMsg = kmalloc(sizeof(struct r3964_message), GFP_KERNEL);      TRACE_M("add_msg - kmalloc %x",(int)pMsg);      if(pMsg==NULL) {

⌨️ 快捷键说明

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