本文介绍了termios VMIN VTIME 和阻塞/非阻塞读操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我正在尝试为 Linux 编写一个简单的 C 串行通信程序.我对阻塞/非阻塞读取和 VMIN/VTIME 关系感到困惑.

I am trying to write a simple C serial communication program for Linux. I am confused about the blocking/non-blocking reads and VMIN/VTIME relationships.

我的问题是,是否应该根据我是否有阻塞/非阻塞打开调用来设置 VMIN/VTIME?

My question is, if I should be settings VMIN/VTIME according to whether I have a blocking/non-blocking open call?

例如,如果我有以下公开电话:

For example, if I have the following open call:

open( "/dev/ttyS0", O_RDWR|O_NONBLOCK|O_NOCTTY)

我应该将 VMIN/VTIME 设置为:

Should I set the VMIN/VTIME to:

.c_cc[VTIME]    = 0;
.c_cc[VMIN]     = 0;

如果我有这样的阻塞模式:

and if I have blocking mode like:

open( "/dev/ttyS0", O_RDWR|O_NOCTTY)

我应该将 VMIN/VTIME 设置为:

should I set the VMIN/VTIME to:

.c_cc[VTIME]    = 0;
.c_cc[VMIN]     = 1;

?

即使端口打开标志设置得当,设置 VMIN/VTIME 有什么区别吗?

Does it make any difference what VMIN/VTIME are set to even though the port open flags are set appropriately?

如果有人能帮助我理解 VMIN/VTIME 和阻塞/非阻塞端口之间的关系,我将不胜感激.

If anybody could help me understand the relationship between VMIN/VTIME and blocking/non-blocking ports I would really appreciate it.

谢谢

推荐答案

Andrey 是对的.在非阻塞模式下,VMIN/VTIME 无效(FNDELAY/O_NDELAY 似乎是 O_NONBLOCK 的 linux 变体,可移植的 POSIX 标志).

Andrey is right. In non-blocking mode, VMIN/VTIME have no effect (FNDELAY / O_NDELAY seem to be linux variants of O_NONBLOCK, the portable, POSIX flag).

在非阻塞模式下对文件使用 select() 时,每个到达的字节都会收到一个事件.在高串行数据速率下,这会影响 CPU.最好对 VMIN 使用阻塞模式,这样 select() 会在触发事件之前等待一个数据块,而 VTIME 来限制延迟,对于小于 VMIN 的块.

When using select() with a file in non-blocking mode, you get an event for every byte that arrives. At high serial data rates, this hammers the CPU. It's better to use blocking mode with VMIN, so that select() waits for a block of data before firing an event, and VTIME to limit the delay, for blocks smaller than VMIN.

Sam 说如果你想确保每半秒获取一次数据,你可以设置 vtime"(VTIME = 5).

Sam said "If you want to make sure you get data every half second you could set vtime" (VTIME = 5).

直觉上,您可能认为这是真的,但事实并非如此.BSD termios 手册页比 linux 解释得更好(尽管它们的工作方式相同).VTIME 定时器是一个interbyte 定时器.它从每个到达串行端口的新字节开始.在最坏的情况下,select() 在触发事件之前最多可以等待 20 秒.

Intuitively, you may expect that to be true, but it's not. The BSD termios man page explains it better than linux (though they both work the same way). The VTIME timer is an interbyte timer. It starts over with each new byte arriving at the serial port. In a worst case scenario, select() can wait up to 20 seconds before firing an event.

假设您有 VMIN = 250、VTIME = 1 和 115200 bps 的串行端口.还假设您有一个连接的设备以​​ 9 cps 的一致速率缓慢发送单个字节.字节之间的时间为 0.11 秒,足以让 0.10 的字节间计时器到期,并且 select() 为每个字节报告一个可读事件.一切都很好.

Suppose you have VMIN = 250, VTIME = 1, and serial port at 115200 bps. Also suppose you have an attached device sending single bytes slowly, at a consistent rate of 9 cps. The time between bytes is 0.11 seconds, long enough for the interbyte timer of 0.10 to expire, and select() to report a readable event for each byte. All is well.

现在假设您的设备将其输出速率提高到 11 cps.字节之间的时间为 0.09 秒.字节间计时器到期的时间还不够长,并且对于每个新字节,它都会重新开始.要获得可读事件,必须满足 VMIN = 250.在 11 cps 时,需要 22.7 秒.看起来您的设备已停止运行,但 VTIME 设计是延迟的真正原因.

Now suppose your device increases its output rate to 11 cps. The time between bytes is 0.09 seconds. It's not long enough for the interbyte timer to expire, and with each new byte, it starts over. To get a readable event, VMIN = 250 must be satisfied. At 11 cps, that takes 22.7 seconds. It may seem that your device has stalled, but the VTIME design is the real cause of delay.

我用两个 Perl 脚本、发送器和接收器、一个双端口串行卡和一根空调制解调器电缆对此进行了测试.我证明它像手册页所说的那样工作.VTIME 是一个字节间计时器,随着每个新字节的到来而重置.

I tested this with two Perl scripts, sender and receiver, a two port serial card, and a null modem cable. I proved that it works as the man page says. VTIME is an interbyte timer that's reset with the arrival of each new byte.

更好的设计是将计时器固定,而不是滚动.它将继续滴答作响,直到到期或满足 VMIN,以先到者为准.现有设计可以修复,但要克服 30 年的遗留问题.

A better design would have the timer anchored, not rolling. It would continue ticking until it expires, or VMIN is satisfied, whichever comes first. The existing design could be fixed, but there is 30 years of legacy to overcome.

在实践中,您可能很少遇到这种情况.但它潜伏着,所以要小心.

In practice, you may rarely encounter such a scenario. But it lurks, so beware.

这篇关于termios VMIN VTIME 和阻塞/非阻塞读操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-08 13:24