Linux中多路串口Select监听方式

申明:本文转自链接:https://www.jianshu.com/p/a293869bbdb8

串口读函数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);                /*  读取串口数据  */
                                /*
                                  ** 数据解析
                                  */
            }
        }
    }
}

原文地址:https://www.cnblogs.com/beyonne/p/11224730.html

时间: 2024-10-05 01:40:26

Linux中多路串口Select监听方式的相关文章

Button的四种监听方式

Button按钮设置点击的四种监听方式 注:加粗放大的都是改变的代码 1.使用匿名内部类的形式进行设置 使用匿名内部类的形式,直接将需要设置的onClickListener接口对象初始化,内部的onClick方法会在按钮被点击的时候执行 第一个活动的java代码: 1 package com.sanlian.buttontest; 2 3 import android.content.Intent; 4 import android.support.v7.app.AppCompatActivit

如何为JOPtionPane的showConfirmDialog对话框中的按钮设置监听

最近刚学了java图形界面编程,想独立写个记事本,过程当中想要为对话框中的按钮设置监听,但是查看了一下api也没找到相应的方法,只找到这个: Returns: an integer indicating the option selected by the user showConfirmDialog这个方法只返回一个int值来标识用户选择了哪一个按钮.找了半天也没找到设置监听的方法..... 就在这时.....灵光一闪~~~~ 很多方法在正常情况下是返回0的,非正常情况返回-1. 于是我就用如

自己定义对象的监听方式

问题描写叙述: 当一个事件的触发不定期的时候,即我们不知道这个触发何时来到,可是我们却要对这个触发运行某些方法,怎样实现? 可能的解决方式: 我当时就想到了,这个问题类似与Android的部件监听(我没有去看Android的源代码,太懒了...).因为如今还在研读Thinking in Java这样的入门书籍,突然来了想法,罗列例如以下,能够通过接口. 以下是我写的一个測试的样例 首先是一个类似Button的部件 package com.example.androidtest2.service;

自定义对象的监听方式

问题描述: 当一个事件的触发不定期的时候,即我们不知道这个触发何时来到,但是我们却要对这个触发执行某些方法,如何实现? 可能的解决方案: 我当时就想到了,这个问题类似与Android的部件监听(我没有去看Android的源码,太懒了...).由于现在还在研读Thinking in Java这种入门书籍,突然来了想法,罗列如下,可以通过接口. 下面是我写的一个测试的例子 首先是一个类似Button的部件 package com.example.androidtest2.service; /** *

简述Java中Http/Https请求监听方法

一.工欲善其事必先利其器 做Web开发的人总免不了与Http/Https请求打交道,很多时候我们都希望能够直观的的看到我们发送的请求参数和服务器返回的响应信息,这个时候就需要借助于某些工具啦.本文将采用Fiddler2作为分析工具,Fiddler很强大,它能记录所有客户端和服务器的http和https请求,允许你监视,设置断点,甚至修改输入输出数据,是越墙抓包之利器.关于工具的介绍可以参考下面的链接: http://www.cnblogs.com/TankXiao/archive/2012/02

关于JAVA中事件分发和监听机制实现的代码实例-绝对原创实用

http://blog.csdn.net/5iasp/article/details/37054171 文章标题:关于JAVA中事件分发和监听机制实现的代码实例 文章地址: http://blog.csdn.net/5iasp/article/details/37054171 作者: javaboy2012Email:[email protected]qq:    1046011462 一.场景假设 假设有博客系统中需要实现如下功能: 系统中用户发布文章,修改文章,删除文章时,需要一些相关的操作

select监听事件的其他用处

1)定时 全赖struct timeval 结构体的定义 2)清空接收缓冲区,获取实时数据. select监听事件的其他用处

QT中使用Event Filter监听按钮事件,Release后按钮不见

Accepted : 42   Submit : 122 Time Limit : 1000 MS   Memory Limit : 65536 KB 题目描述 五虎棋是流传在东北民间的一种游戏,GG小的时候,经常被表哥虐得很惨. 由于各个地区的规则可能不大相同,并且GG的回忆不一定很准,所以,如果规则和你平常玩的的有冲突,请以这里为主. 棋盘是横五条,纵五条直线,形成25个交叉点,双方轮流把棋子放到交叉点上 (由于所需各自和棋子数目不多,才12+13,GG小的时候,用的是象棋的棋盘和棋子,真的

Oracle Enterprise Linux 64-bit 下Oracle11g的监听配置修改及测试步骤

测试环境:Oracle Enterprise Linux 64-bit (5.8版本) + Oracle 11g 64位 相关说明: Oracle11g64位软件的安装位置为/u01/app/oracle/product/11.2.0/dbhome_1 ,数据库名为默认的orcl,Linux虚拟机的IP设置为192.168.1.121 一.修改listener.ora文件内容 命令:[[email protected] ~]$ vi /u01/app/oracle/product/11.2.0/