【发布时间】:2012-05-18 08:00:21
【问题描述】:
我正在使用文件描述符和 posix/unix read() 函数从 C++ 中的串行端口读取字节。在本例中,我从串口读取 1 个字节(为清楚起见,省略了波特率设置和类似设置):
#include <termios.h>
#include <fcntl.h>
#include <unistd.h>
int main(void)
{
int fd = open("/dev/ttyS0", O_RDWR | O_NOCTTY);
char buf[1];
int bytesRead = read(fd, buf, 1);
close(fd);
return 0;
}
如果连接到 /dev/ttyS0 的设备没有发送任何信息,程序将挂起。如何设置超时?
我尝试过这样设置超时:
struct termios options;
tcgetattr(fd, &options);
options.c_cc[VMIN] = 0;
options.c_cc[VTIME] = 10;
tcsetattr(fd, TCSANOW, &options);
我认为它应该给 1 秒超时,但它没有区别。我想我误解了 VMIN 和 VTIME。 VMIN 和 VTIME 是干什么用的?
然后我在网上搜索,发现有人在谈论 select() 函数。这是解决方案吗?如果是这样,如何将其应用于上面的程序以使 1 秒超时?
感谢任何帮助。在此先感谢:-)
【问题讨论】:
-
使用
tcsetattr()的VTIME并不简单;它需要一些串行驱动程序不支持的其他模式设置。请参阅我的答案以获得一般解决方案。 -
这是我在网上看到的关于 VMIN 和 VTIME http://unixwiz.net/techtips/termios-vmin-vtime.html 的最佳解释。根据文章,当 ICANON 位关闭时,它会启用“原始模式”来改变 VMIN 和 VTIME 的解释。设置 ICANON 位将使代码按预期工作。
-
一般在设置
options.c_cc[VMIN] = 0;options.c_cc[VTIME] = 10;时。read()应该在一个或多个字节可用时返回,否则会超时。在后一种情况下,read 应该表明已经读取了 0 个字节。