linux串口数据读取方法

linux串口数据读取方法

  |

Linux下的串口操作说简单也简单,说复杂也复杂。简单在于其读写调用与文件操作一致,使用方便。但是参数设置相对复杂,而且在一些操作上需要注意技巧。

在串口数据读取方法上,有一点很值得注意,就是操作超时退出处理。如果没有这方面的处理,只用使用read()函数阻塞读取,那么一旦串口buffer中没有数据可读,将会导致进程卡死,造成通信中断。

超时保护措施有几种:

  1. 采用中断方式读取。
  2. 启动一个定时器手动进行计时退出保护。
  3. 使用select查询。

前两种方式使用的话当然没有问题,但是用法比较复杂,如果不是有很特殊的要求,不建议使用,方法3完全可以满足一般使用,而且代码简洁,独立性很强。

select()函数的原型是:

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

其作用是监视文件描述符(句柄)的状态,如果该描述符状态发生预期的变化,则返回关联值。语言表达的可能比较复杂,从函数的几个参数逐步来看吧。

int nfds,文件描述符+1 ,存在多个文件描述符时,取最大的加1。

fd_set *readfds,存放读状态的数据体指针,如果设置了该值,则表示文件描述符出现可读状态时返回。

fd_set *writefds,与上面类似,不同的是存在可写状态时返回。

fd_set *exceptfds,这里是存在异常状态时返回,一般没有使用。

struct timeval *timeout,超时参数结构体,原型为:

struct timeval {
long tv_sec; /* 秒*/
long tv_usec; /* 微秒*/
};

在调用select()函数前,应该先进行初始化和绑定,FD_ZERO()进行清零,FD_SET()绑定描述符。

示例:

/*—————————–Start——————————*/

int fd; //文件描述符

int rtv; //存放返回值

fdset fs_read; //读状态数据集(这个名字不好取,只可意会吧)

struct timeval timeout;//超时设置参数结构体

FD_ZERO(&fs_read); //数据集清零

FD_SET(fd, &fs_read);//绑定描述符与数据集

rtv = select(fd + 1, &fs_read, NULL, NULL, &timeout);//查询改描述符关联设备是否存在数据可读

if(rtv == -1)//select函数调用失败

{

perror(“select() Error!”);

}

else if(rtv) //存在可读数据,准备读取

{

read(……..);

//GO ON….

}

/*—————————–End——————————*/

这里需要注意:

  • 每次调用select()函数前,必须使用FD_ZERO()进行清零,否则select()在一次超时后将会根据之前的数据,直接超时返回。
  • 串口通信时,如果出现校验失败,必须先将串口buffer中剩余的数据读出清除,然后重新开始下一次的握手。否则,由于buffer中一直有残留数据,select()可正常返回,导致数据定长读取时无法通过校验,进入恶性死循环。
  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值