如何将字节间延迟超时设置为毫秒?

5 linux serial-port termios

我目前正在使用 termios 在 Linux 中进行串行通信。

我需要将字符间超时设置为 5 毫秒。

我找到了一种使用 VMIN 和 VTIME 设置字符间超时的方法,其中 VMIN 必须为 VMIN > 0 且 VTIME > 0。

问题是我需要将VTIME设置为5ms,但VTIME是以十分之一秒表示的。

VTIME数据类型是unsigned char,所以我不能将其设置为0.05。

有谁知道是否有办法解决这个问题?

saw*_*ust 2

我需要将字符间超时设置为 5 毫秒。
...
有谁知道是否有办法解决这个问题?

不,无法设置比 100 毫秒更短的 termios 超时。
根据您的硬件和内核配置,此超时可能根本不可靠,特别是当您尝试检测时间分隔的消息时。
termios 处理至少位于 UART 设备驱动程序之上的完整层(请参阅 Linux 串行驱动程序)。
除非您的内核配置为确保 UART 驱动程序的下半部分和 termios 的 kworker 线程具有高优先级和低延迟,否则无法准确或可靠地确定短字符间间隔。

如果 UART 使用 FIFO 来缓冲传入数据,则该硬件会掩盖软件可以检测到的字符间距。
同样,当 UART 驱动程序使用 DMA 存储接收到的数据时,字符间时序将被掩盖。
使用 DMA,CPU 不会参与处理接收到的数据,直到 DMA 操作完成,并且有关任何字符间分隔的所有临时信息都消失了。
(使用 DMA 时,帧错误和/或奇偶校验错误等关键信息很难/不可能精确定位到特定字节。)
即使没有 DMA,termios 也只能使用基于通过 tty 翻转缓冲区传输数据的时序(这是从导线上的计时中删除的一层)。

一些 UART 确实具有帮助通过空闲线检测消息结束的硬件。
例如,Atmel/Microchip ATSAMA5 和 AT91SAM9 SoC 的 USART 具有接收器超时功能,可测量每个接收帧后的空闲时间。
当该空闲线时间超过指定值时,可以生成中断。
Atmel USART 的 Linux 驱动程序通常使用接收器超时中断来(提前)终止当前 DMA 接收操作,并将 DMA 缓冲区的内容复制到 tty 翻转缓冲区。

总之,您不能或不应仅依赖 VMIN 和 VTIME 设置来检测时间分隔的消息。请参阅解析时间分隔的 UART 数据
消息数据包需要具有分隔符/标记字符/字节,以便可以可靠地解析和验证消息。有关通过本地缓冲区有效使用系统调用的示例,
请参阅解析来自串行端口的完整消息。