【发布时间】:2013-04-11 23:13:14
【问题描述】:
我有一个通过 termios 串行 API 使用的 FTDI USB 串行设备。我设置了端口,以便它在半秒内调用 read() 超时(通过使用 VTIME 参数),这在 Linux 和 FreeBSD 上都有效。然而,在 OpenBSD 5.1 上,read() 调用会在没有数据可用时永远阻塞(见下文。)我希望 read() 在 500 毫秒后返回 0。
谁能想到 termios API 在 OpenBSD 下的行为会有所不同,至少在超时功能方面?
编辑:无超时问题是由链接到 pthread 引起的。无论我是否实际使用任何 pthread、互斥锁等,简单地链接到该库都会导致 read() 永远阻塞,而不是根据 VTIME 设置超时。同样,这个问题只在 OpenBSD 上出现——Linux 和 FreeBSD 可以正常工作。
if ((sd = open(devPath, O_RDWR | O_NOCTTY)) >= 0)
{
struct termios newtio;
char input;
memset(&newtio, 0, sizeof(newtio));
// set options, including non-canonical mode
newtio.c_cflag = (CREAD | CS8 | CLOCAL);
newtio.c_lflag = 0;
// when waiting for responses, wait until we haven't received
// any characters for 0.5 seconds before timing out
newtio.c_cc[VTIME] = 5;
newtio.c_cc[VMIN] = 0;
// set the input and output baud rates to 7812
cfsetispeed(&newtio, 7812);
cfsetospeed(&newtio, 7812);
if ((tcflush(sd, TCIFLUSH) == 0) &&
(tcsetattr(sd, TCSANOW, &newtio) == 0))
{
read(sd, &input, 1); // even though VTIME is set on the device,
// this read() will block forever when no
// character is available in the Rx buffer
}
}
【问题讨论】:
-
你使用的是-pthread还是-lpthread?
-
对不起,我又看到标题了;)
-
你能在我们切换到默认rthreads的OpenBSD 5.2上试试吗?在我的 5.3 系统上,您的示例不会阻塞。 obsd/amd64.
-
清零
termios结构不是正确的初始化方法。您应该调用tcgetattr(),然后修改 标志。您正在使用 POSIX 接口,并且您应该遵循他们的可移植性实践。见Serial Programming Guide for POSIX Operating Systems。cfset?speed()的论点也看起来很假; “波特率”不是数值,而是编码值。 -
对 rthreads 的更改显然很重要——代码在 OpenBSD 5.2 上可以正常工作!另外,我将更改
termiosstruct init 以便它首先调用tcgetattr(),但我看不出我可以做些什么来将参数更改为cfset?speed()——在7812 波特中没有编码值termios 标头。
标签: serial-port pthreads openbsd