linux中select监听多路串口数据

串口读函数read是阻塞函数,多路串口接收不太好处理,如果每路串口使用单独的线程接收浪费资源,使用select()函数监听多路串口数据可以把所有接收的数据在一个线程中处理,类似QT中的槽函数功能。
1、函数原型介绍

int select(int nfds, fd_set *rdfds, fd_set *wtfds, fd_set *exfds, struct timeval *timeout)

入口参数:
①:ndfs:select() 中监视的文件句柄,一般设为要监视的文件中的最大文件号加一。
②:rdfds:select()监视的可读文件句柄集合,当rdfds映象的文件句柄状态变成可读时系统告诉select函数返回。这个集合中有一个文件可读,select就会返回一个大于0的值,表示有文件可读,如果没有可读的文件,则根据timeout参数再判断是否超时,若超出timeout的时间,select返回0,若发生错误返回负值,可以传入NULL值,表示不关心任何文件的读变化;
③:wtfds: select()监视的可写文件句柄集合,当wtfds映象的文件句柄状态变成可写时系统告诉select函数返回。
如果这个集合中有一个文件可写,select就会返回一个大于0的值,表示有文件可写,
如果没有可写的文件,则根据timeout参数再判断是否超时,
若超出timeout的时间,select返回0,若发生错误返回负值,
可以传入NULL值,表示不关心任何文件的写变化。
④:exfds:select()监视的异常文件句柄集合,当exfds映象的文件句柄上有特殊情况发生时系统会告诉select函数返回。
⑤:timeout:select()的超时结束时间
配置函数:
FD_ZERO(fd_set *fdset):清空fdset与所有文件句柄的联系。
FD_SET(int fd, fd_set *fdset):建立文件句柄fd与fdset的联系。
FD_CLR(int fd, fd_set *fdset):清除文件句柄fd与fdset的联系。
FD_ISSET(int fd, fdset *fdset):检查fdset联系的文件句柄fd是否可读写,>0表示可读写。

2、

int main(void)
{
    int     uart01_fd ,uart02_fd;
    fd_set  recv_fds;  /* 定义接收fds  一个存放文件描述符(file descriptor),即文件句柄的聚合,实际上是一long类型的数组 */
    int     maxfd   = 0;    /* 定义最大句柄 */
    int     fd_result;
    struct  timeval tv;       /* 超时时间 */

    uart01_fd   =    open("/dev/ttyO1", O_RDWR | O_NOCTTY); /* 打开串口 */
    if(uart01_fd < 0) {
        printf("open /dev/ttyO1 error \r\n");
               // return -1;
    }
    
    uart02_fd   =    open("/dev/ttyO2", O_RDWR | O_NOCTTY); /* 打开串口 */
    if(uart02_fd < 0) {
        printf("open /dev/ttyO2 error \r\n");
               // return -1;
    }
    
    tv.tv_sec   = 10;       //设定超时时间 
    tv.tv_usec  = 0;          //10000us = 10ms
    if(uart01_fd > maxfd)                            /* maxfd 为最大值  */
    {
        maxfd = uart01_fd;
    }
    if(uart02_fd > maxfd)
    {
        maxfd = uart01_fd;
    }
    for(;;)
    {   
        /* 注意每次都要重新设置 */
        FD_ZERO(&recv_fds);
        FD_SET(uart01_fd,&recv_fds);                                /* 分别把句柄加入读监视集合里去   */
        FD_SET(uart02_fd,&recv_fds);                                /* 分别把句柄加入读监视集合里去   */

        fd_result = select(maxfd + 1, &recv_fds, NULL, NULL, &tv);  /* 注意是最大值加1                   */
        if(fd_result < 0)
        {
                printf("select err");                               /* select函数出错                 */
            usleep(10000);
            continue;
        }
        else if(fd_result == 0)
        {
            // printf("select time out \n"); /* 在设定的tv时间内,socket的状态没有发生变化 */
            usleep(10000);
            continue;
        }
        else                                                        /* 开始读数据 */
        {
            if(FD_ISSET(uart01_fd, &recv_fds))                      /* 先判断一下是哪个句柄可读 */
                {
                uiLen  = read(uart01_fd,ucbuff,0xff);               /*  读取串口数据  */
                                /*
                                  ** 数据解析 
                                  */        
            }   
            if(FD_ISSET(uart02_fd, &recv_fds))                      /* 先判断一下是哪个句柄可读 */
                {
                uiLen  = read(uart02_fd,ucbuff,0xff);                /*  读取串口数据  */
                                /*
                                  ** 数据解析 
                                  */        
            }
        }
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,907评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,546评论 1 289
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,705评论 0 238
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,624评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,940评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,371评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,672评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,396评论 0 195
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,069评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,350评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,876评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,243评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,847评论 3 231
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,004评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,755评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,378评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,266评论 2 259

推荐阅读更多精彩内容

  • 串口操作 串口操作需要的头文件 #include /*标准输入输出定义*/ #include /*标准函数库定...
    旅行家John阅读 1,194评论 0 3
  • 本文摘抄自linux基础编程 IO概念 Linux的内核将所有外部设备都可以看做一个文件来操作。那么我们对与外部设...
    lintong阅读 1,506评论 0 4
  • I/O复用基本概念 I/O多路复用技术通过把多个I/O的阻塞复用到同一个select的阻塞上,从而使得系统在单线程...
    Ycres阅读 901评论 0 0
  • select,poll,epoll都是IO多路复用的机制。I/O多路复用就是通过一种机制,可以监视多个描述符,一旦...
    yeying12321阅读 1,602评论 0 5
  • 概念 首先要说明几个概念: 用户空间和内核空间 进程切换 进程的阻塞 文件描述符 缓存 I/O 用户空间与内核空间...
    jiangmo阅读 921评论 0 9