mysql监听串口_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); /* 读取串口数据 */

/*

** 数据解析

*/

}

}

}

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值