简体   繁体   English

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

[英]Linux Serial Port: Blocking Read with Timeout

I have studied many useful threads and some tutorials, but I'm still having some issues with something that should be very simple. 我已经研究了许多有用的线程和一些教程,但我仍然遇到一些应该非常简单的问题。 For reference here are some threads that I've perused: 这里参考一些我已经阅读过的主题:

How to implement a timeout in read function call? 如何在读取函数调用中实现超时?

how to open, read, and write from serial port in C 如何在C中从串口打开,读取和写入

At any rate, I have a bit of a problem. 无论如何,我有点问题。 My code works fine if I receive data. 如果我收到数据,我的代码工作正常。 If I don't, the read() function stalls and the only way to get out of my program is to use kill -9 (NOTE: I use signal handling to signal to the thread reading the serial data to terminate. This is not the culprit, the read() call still stalls even if I have removed my signal handling). 如果我不这样做,read()函数会停止并且退出程序的唯一方法是使用kill -9(注意:我使用信号处理来向读取串行数据的线程发出信号以终止。这不是罪魁祸首,即使我已经删除了我的信号处理,read()调用仍然停止。 What I'm trying to do is to have a read that blocks and reads a chunk at a time (therefore saving CPU usage), however if the read receives no data, I wan't it to timeout. 我想要做的是读取一次阻塞和读取一个块(因此节省CPU使用率),但是如果读取没有数据,我就不会超时。

Here are the settings that I'm applying to the port: 以下是我正在应用于端口的设置:

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

I then set these settings with tcsetattr() and confirm that the port received the settings via tcgetattr(). 然后我使用tcsetattr()设置这些设置,并确认端口通过tcgetattr()接收设置。 I'm thinking that my settings may be conflicting, because my reads appear to be blocking and wait until 64 bytes are received, but do not do anything with regards to the timeout. 我认为我的设置可能有冲突,因为我的读取似乎是阻塞并等待直到收到64个字节,但是没有做任何关于超时的事情。 I understand that I can use select() to deal with a timeout, but I'm hoping to avoid the multiple system calls. 我知道我可以使用select()来处理超时,但我希望避免多个系统调用。

As always, thanks in advance for the help. 一如既往,感谢您的帮助。

From man 3 termios : 来自man 3 termios

MIN > 0; MIN> 0; TIME > 0: TIME specifies the limit for a timer in tenths of a second. TIME> 0:TIME指定计时器的限制,以十分之一秒为单位。 Once an initial byte of input becomes available, the timer is restarted after each further byte is received. 一旦输入的初始字节变为可用,则在接收到每个进一步的字节后重新启动定时器。 read(2) returns either when the lesser of the number of bytes requested or MIN byte have been read, or when the inter-byte timeout expires. read(2)在请求的字节数或MIN字节的较小者或者字节超时到期时返回。 Because the timer is only started after the initial byte becomes available, at least one byte will be read. 由于定时器仅在初始字节可用后启动,因此将至少读取一个字节。

Note that the timer does not start until at least one byte of data is received. 请注意,在收到至少一个字节的数据之前,定时器不会启动 After receiving that first data byte, the read will timeout if there is ever a gap of TIME tenths of a second between receiving consecutive data bytes. 在接收到第一个数据字节后,如果在接收连续数据字节之间存在TIME十分之一秒的间隔,则读取将超时。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM