一尘不染

Linux串行端口:阻止超时读取

linux

我研究了许多有用的线程和一些教程,但是仍然存在一些问题,这些问题应该非常简单。作为参考,这里是我细读的一些线程:

无论如何,我有一个问题。如果我收到数据,我的代码可以正常工作。如果不这样做,则read()函数将停顿,退出程序的唯一方法是使用kill
-9(注意:我使用信号处理来发信号通知线程读取串行数据以终止。这不是罪魁祸首,即使我删除了信号处理,read()调用仍然停止。我正在尝试做的是一次读取,该读取一次阻塞并读取一个块(从而节省了CPU使用量),但是,如果读取未接收到任何数据,则我不想使其超时。

这是我要应用到端口的设置:

struct termios serial_struct;
serial_struct.c_cflag = B115200 | CS8 | CLOCAL | CREAD;
serial_struct.c_iflag = IGNPAR;
serial_struct.c_oflag = 0;
serial_struct.c_lflag = 0;
serial_struct.c_cc[VTIME] = 1;  // timeout after .1s that isn't working
serial_struct.c_cc[VMIN] = 64;  // want to read a chunk of 64 bytes at a given time

然后,我使用tcsetattr()设置这些设置,并确认端口通过tcgetattr()接收了设置。我在想我的设置可能会发生冲突,因为我的读取似乎正在阻塞并且要等到接收到64个字节之后,才对超时不做任何事情。我知道我可以使用select()处理超时,但是我希望避免多次系统调用。

与往常一样,在此先感谢您的帮助。


阅读 303

收藏
2020-06-07

共1个答案

一尘不染

来自man 3 termios

MIN> 0; TIME>
0:TIME以十分之一秒为单位指定计时器的限制。一旦输入的初始字节可用,则在接收到每个其他字节后重启定时器。当读取了所请求的字节数或MIN字节中的较小者时,或者字节间超时到期时,read(2)返回。因为仅在初始字节可用后才启动计时器,所以将至少读取一个字节。

请注意,直到接收到至少一个字节的数据后,计时器才会 启动 。接收到第一个数据字节后,如果在接收到连续数据字节之间有十分之一秒的时间间隔,则读取将超时。

2020-06-07