【BUGLIST】串口编程不读数据

1.背景

最近做串口服务器遇到轮询从串口文件描述符中读数据,但是读不到数据:源代码为

   uart_fd= open(uart);
    while(1)
    {
     
        read(uart_fd,buff,sizeof(buff));
    }

2.原因

 函数定义:ssize_t read(int fd, void * buf, size_t count);

函数说明:read()会把参数fd所指的文件传送count 个字节到buf 指针所指的内存中。

返回值:返回值为实际读取到的字节数, 如果返回0, 表示已到达文件尾或是无可读取的数据。
若参数count 为0,read()不会有作用并返回0。

注意:read时fd中的数据如果小于要读取的数据,就会引起阻塞

3 解决办法

3.1 读取小数量的数据(每次只读一个数据(视能力情况而设))

626    while1627     {
        
628         res=0;
629         memset(buff, 0, sizeof(buff));
630         res = xxx_buart_read_bytes(cldev_info->tty_fd, &revdata, 1);
638         ret = xxx_tcp_write(cldev_info->sock_fd, &revdata, res);
646     }

3.2 使用epoll,监听串口数据,

766 static int xxx_epoll_add_event(int epollfd,int fd,int state)
767 {
     
768     int epoll_res = 0;
769     struct epoll_event ev;
770     ev.events = state;
771     ev.data.fd = fd;
772     epoll_res=epoll_ctl(epollfd,EPOLL_CTL_ADD,fd,&ev);
773     return epoll_res;
774 }
775
776
777 static int xxx_epoll_delete_event(int epollfd,int fd,int state)
778 {
     
779     int epoll_res = 0;
780     struct epoll_event ev;
781     ev.events = state;
782     ev.data.fd = fd;
783     epoll_res=epoll_ctl(epollfd,EPOLL_CTL_DEL,fd,&ev);
784     return epoll_res;
785 }
786		xxx_epoll_add_event(tcpcl_info->pollfd, tcpcl_info->tty_fd, EPOLLIN);


666    while(1)
667     {
     
668         res = 0;
669         //1.读取有效的线程,将数据放入队列,并使用信号量通知所有的线程
670         epoll_res = epoll_wait(dev_info->pollfd,get_events,((LIG_TTY_MAX<<1)+1),1000);
671         if(epoll_res==-1){
     
672             pr_log(LOG_ERR,"epoll_wait err %d:%s\n",errno,strerror(errno));
673             continue;
674         }
675         if(epoll_res==0) {
     
676             //pr_log(LOG_WARNING,"epoll_wait time out\n");
677             continue;
678         }

679        struct epoll_event get_events[(LIG_TTY_MAX <<1 ) + 1];
680         while(epoll_res)
681         {
     
682             epoll_res--;
683             OBJ_LIG_TCPCL_DEV * tcpcl_info = NULL;
684             for(fori=0;fori<LIG_TTY_MAX;fori++)
685             {
     
96                 if(dev_info->tcpcl_info[fori].tty_fd == get_events[epoll_res].data.fd)
697                 {
     
698                     tcpcl_info = &dev_info->tcpcl_info[fori];
699                     if(get_events[epoll_res].events & EPOLLIN)
700                     {
     
701                         memset(getbuff, 0, sizeof(getbuff));
702                         res = xxx_buart_read_bytes(tcpcl_info->tty_fd, getbuff, sizeof(getbuff));
703                       }
704                   }
705              }

4 解决阻塞死等待的办法

4.1 阻塞死等待的缺点

【BUGLIST】串口编程不读数据_第1张图片

4.2 办法一:非阻塞、忙轮询

【BUGLIST】串口编程不读数据_第2张图片

4.3 办法二:select

【BUGLIST】串口编程不读数据_第3张图片

4.4 办法三:epoll

【BUGLIST】串口编程不读数据_第4张图片

4.5 什么是poll

  • 与select,poll一样,对I/O多路复用的技术
  • 只关心“活跃”的链接,无需遍历全部描述符集合
  • 能够处理大量的链接请求(系统可以打开的文件数目)

你可能感兴趣的:(BUGLIST,epoll,多线程)