免费注册 查看新帖 |

ChinaUnix.net

  平台 论坛 博客 文库 频道自动化运维 虚拟化 储存备份 C/C++ PHP MySQL 嵌入式 Linux系统
最近访问板块 发新帖
查看: 1569 | 回复: 0

[应用] linux串口poll多路读取的数据被截断问题 [复制链接]

论坛徽章:
0
发表于 2018-10-26 15:26 |显示全部楼层
本帖最后由 stm32f103vct 于 2018-10-26 15:28 编辑
  1. /****************************************************************************
  2. *                                                                          *
  3. * Copyright (c) 2014 Nuvoton Technology Corp. All rights reserved.         *
  4. *                                                                          *
  5. ****************************************************************************/

  6. /****************************************************************************
  7. *
  8. * FILENAME
  9. *     uart_test.c
  10. *
  11. * VERSION
  12. *     1.0
  13. *
  14. * DESCRIPTION
  15. *     This is the test program used to test the UARTs on NUC970 EV board
  16. *
  17. * DATA STRUCTURES
  18. *     None
  19. *
  20. * FUNCTIONS
  21. *     None
  22. *
  23. * HISTORY
  24. *     
  25. *
  26. * REMARK
  27. *     None
  28. ****************************************************************************/
  29. #include     <stdio.h>
  30. #include     <stdlib.h>
  31. #include     <unistd.h>
  32. #include     <sys/types.h>
  33. #include     <sys/stat.h>
  34. #include     <fcntl.h>
  35. #include     <termios.h>  
  36. #include     <errno.h>
  37. #include     <string.h>
  38. #include         <signal.h>
  39. #include    <pthread.h>

  40. #define FALSE 0
  41. #define TRUE  1

  42. int fd[2];

  43. pthread_t threads[10];
  44. char ucbuff[50];
  45. char buf[] = "hello ZLG!";

  46. static struct termios newtios,oldtios; /*termianal settings */
  47. static int saved_portfd=-1;            /*serial port fd */


  48. static void reset_tty_atexit(void)
  49. {
  50.         if(saved_portfd != -1)
  51.         {
  52.                 tcsetattr(saved_portfd,TCSANOW,&oldtios);
  53.         }
  54. }

  55. /*cheanup signal handler */
  56. static void reset_tty_handler(int signal)
  57. {
  58.         if(saved_portfd != -1)
  59.         {
  60.                 tcsetattr(saved_portfd,TCSANOW,&oldtios);
  61.         }
  62.         _exit(EXIT_FAILURE);
  63. }

  64. static int open_port(const char *portname)
  65. {
  66.         struct sigaction sa;
  67.         int portfd;

  68.         printf("opening serial port:%s\n",portname);
  69.         /*open serial port */
  70.         if((portfd=open(portname,O_RDWR | O_NOCTTY)) < 0 )
  71.         {
  72.                    printf("open serial port %s fail \n ",portname);
  73.                    return portfd;
  74.         }

  75.         /*get serial port parnms,save away */
  76.         tcgetattr(portfd,&newtios);
  77.         memcpy(&oldtios,&newtios,sizeof newtios);
  78.         /* configure new values */
  79.         cfmakeraw(&newtios); /*see man page */
  80.         newtios.c_iflag |=IGNPAR; /*ignore parity on input */
  81.         newtios.c_oflag &= ~(OPOST | ONLCR | OLCUC | OCRNL | ONOCR | ONLRET | OFILL);
  82.         newtios.c_cflag = CS8 | CLOCAL | CREAD;
  83.         newtios.c_cc[VMIN]=1; /* block until 1 char received */
  84.         newtios.c_cc[VTIME]=0; /*no inter-character timer */
  85.         /* 115200 bps */
  86.         cfsetospeed(&newtios,B115200);
  87.         cfsetispeed(&newtios,B115200);
  88.         /* register cleanup stuff */
  89.         atexit(reset_tty_atexit);
  90.         memset(&sa,0,sizeof sa);
  91.         sa.sa_handler = reset_tty_handler;
  92.         sigaction(SIGHUP,&sa,NULL);
  93.         sigaction(SIGINT,&sa,NULL);
  94.         sigaction(SIGPIPE,&sa,NULL);
  95.         sigaction(SIGTERM,&sa,NULL);
  96.         /*apply modified termios */
  97.         saved_portfd=portfd;
  98.         tcflush(portfd,TCIFLUSH);
  99.         tcsetattr(portfd,TCSADRAIN,&newtios);
  100.         return portfd;
  101. }


  102. /**
  103. *@breif         main()
  104. */
  105. int main(int argc, char **argv)
  106. {
  107.          fd_set  recv_fds;  /* 定义接收fds  一个存放文件描述符(file descriptor),即文件句柄的聚合,实际上是一long类型的数组 */
  108.             int     maxfd   = 0;    /* 定义最大句柄 */
  109.          int     fd_result;
  110.          struct  timeval tv;       /* 超时时间 */
  111.         char *dev[10]={"/dev/ttyS1", "/dev/ttyS2"};
  112.         unsigned int i,len;

  113.         printf("\n demo uart1/uart2 external loop back function \n");

  114.         for(i = 0; i < 2; i++)
  115.         {
  116.                 if((fd[i] = open_port(dev[i]))<0)
  117.                            return -1;
  118.         }
  119.             tv.tv_sec   = 10;       //设定超时时间
  120.             tv.tv_usec  = 0;          //10000us = 10ms
  121.         if(fd[0] > maxfd)                            /* maxfd 为最大值  */
  122.             {
  123.                         maxfd = fd[0];
  124.             }
  125.             if(fd[1] > maxfd)
  126.             {
  127.                 maxfd = fd[1];
  128.             }
  129.         for(;;)
  130.             {   
  131.                 /* 注意每次都要重新设置 */
  132.                 FD_ZERO(&recv_fds);
  133.                 FD_SET(fd[0],&recv_fds);                                /* 分别把句柄加入读监视集合里去   */
  134.                 FD_SET(fd[1],&recv_fds);                                /* 分别把句柄加入读监视集合里去   */

  135.                 fd_result = select(maxfd + 1, &recv_fds, NULL, NULL, &tv);  /* 注意是最大值加1                   */
  136.                 if(fd_result < 0)
  137.                 {
  138.                 printf("select err");                               /* select函数出错                 */
  139.             usleep(10000);
  140.             continue;
  141.                 }
  142.          else if(fd_result == 0)
  143.          {
  144.             // printf("select time out \n"); /* 在设定的tv时间内,socket的状态没有发生变化 */
  145.             usleep(10000);
  146.             continue;
  147.          }
  148.          else                                                        /* 开始读数据 */
  149.          {
  150.             if(FD_ISSET(fd[0], &recv_fds))                      /* 先判断一下是哪个句柄可读 */
  151.                 {
  152.                 len  = read(fd[0],ucbuff,0xff);               /*  读取串口数据  */
  153.                 printf("%d \n", len);
  154.                                 /*
  155.                                   ** 数据解析
  156.                                   */        
  157.             }   
  158.             if(FD_ISSET(fd[1], &recv_fds))                      /* 先判断一下是哪个句柄可读 */
  159.                 {
  160.                 len  = read(fd[1],ucbuff,0xff);                /*  读取串口数据  */
  161.                                 /*
  162.                                   ** 数据解析
  163.                                   */        
  164.                }
  165.          }
  166.         printf("%s \n", ucbuff);
  167.        }
  168.         

  169.         return(0);
  170.          
  171. }
复制代码
结果如图数据被截断:
23840478.png
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

数据风云,十年变迁
DTCC 第十届中国数据库技术大会已启航!

2019年5月8日~5月10日,由IT168旗下ITPUB企业社区平台主办的第十届中国数据库技术大会(DTCC2019),将在北京隆重召开。大会将邀请百余位行业专家,就热点技术话题进行分享,是广大数据领域从业人士的又一次年度盛会和交流平台。与SACC2018类似,本届大会将采用“3+2”模式:3天传统技术演讲+2天深度主题培训。大会不仅提供超100场的主题演讲,还会提供连续2天的深度课程培训,深化数据领域的项目落地实践方案。
DTCC2019,一场值得期待的数据技术盛会,殷切地希望您报名参与!

活动入口>>
  

北京盛拓优讯信息技术有限公司. 版权所有 16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122
中国互联网协会会员  联系我们:huangweiwei@it168.com
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP