linux - 如何将字节间延迟超时设置为毫秒?
问题描述
我目前正在使用 termios 在 Linux 中进行串行通信。
我需要将字符间超时设置为 5 毫秒。
我找到了一种使用 VMIN 和 VTIME 设置字符间超时的方法,其中 VMIN 必须是 VMIN > 0 和 VTIME > 0。
问题是我需要将 VTIME 设置为 5ms,但 VTIME 以十分之一秒表示。
VTIME 数据类型是无符号字符,所以我不能将它设置为 0.05。
有谁知道是否有办法解决这个问题?
解决方案
I need to set an intercharacter timeout to 5ms.
...
Does anyone know if there is some way around this?
No, there is no way to set a shorter termios timeout than 100 ms.
Depending on your hardware and kernel configuration, this timeout may not be reliable at all, especially if you are trying to detect time-separated messages.
The termios handling is at least a full layer above the UART device driver (see
Linux serial drivers).
Unless your kernel is configured to ensure that the bottom-half of the UART driver and the kworker threads for termios are high priority and low latency, then short intercharacter intervals cannot be accurately or reliably determined.
If the UART utilizes a FIFO to buffer incoming data, then that hardware obscures the intercharacter spacing that the software can detect.
Similarly when the UART driver is using DMA to store the received data, intercharacter timing will be obscured.
With DMA the CPU is not involved with handling the received data until the DMA operation is complete, and all temporal information about any intercharacter separation is gone.
(Crucial information such as framing error and/or parity error is difficult/impossible to pinpoint to a specific byte when using DMA.)
Even without DMA, termios will only be able to use timing based on the transfer of data through the tty flip buffers (which is a layer removed from the timing on the wire).
Some UARTs do have hardware that assist in detecting the end-of-message by idle line.
For example Atmel/Microchip ATSAMA5 and AT91SAM9 SoCs have USARTs with a Receiver Timeout feature that measures the idle time after each received frame.
When this idle line time exceeds a specified value, an interrupt can be generated.
The Linux driver for the Atmel USART typically uses the receiver-timeout interrupt to (prematurely) terminate the current DMA receive operation, and copy the contents of the DMA buffer to the tty flip buffer.
In summary you cannot or should not rely solely on VMIN and VTIME settings to detect time-separated messages. See Parsing time-delimited UART data.
The message packets need to have delimiter/sentinel characters/bytes so that messages can be reliably parsed and validated.
See parsing complete messages from serial port for an example of efficient use of syscalls with a local buffer.
推荐阅读
- python-3.x - 即使输入相同,相同的代码也会给出不同的输出
- android - 如何在 java 中对 JSON API 进行排序或过滤
- node.js - 无法再次使用 Jest、Supertest、Passport、Koa2 在测试中发送经过身份验证的请求
- netbeans - netbeans 在同一选项卡中打开文件
- c# - Newtonsoft Json.NET 不序列化 [过时] 属性
- rust - 是否有从标准输入或生锈文件中读取的特征?
- docker - 在 travis ci 中,docker 登录失败
- ios - 更改自定义 UIButton 状态时的 UI 问题
- java - 如何在 HierarchicalStreamReader 转换器中使用 xml 标签获取 xml 元素的值
- mod-auth-openidc - 提交表单时刷新 mod_auth_openidc 上的访问令牌