【发布时间】:2021-01-28 16:13:22
【问题描述】:
正如您在本教程中所见,COM 端口的默认延迟计时器为 16 毫秒。
COM Port Latency
但在大多数情况下,我们想要最小的延迟。
在互联网上,我们看到很多解释为什么这个值应该尽可能小,但永远不要选择大的值。
那么为什么默认值是 16ms 而可能是 1ms 呢?
【问题讨论】:
标签: windows serial-port uart bus
正如您在本教程中所见,COM 端口的默认延迟计时器为 16 毫秒。
COM Port Latency
但在大多数情况下,我们想要最小的延迟。
在互联网上,我们看到很多解释为什么这个值应该尽可能小,但永远不要选择大的值。
那么为什么默认值是 16ms 而可能是 1ms 呢?
【问题讨论】:
标签: windows serial-port uart bus
以更大的块传输数据更节省 CPU。如果您有 1 毫秒的延迟,您的串行端口可能会导致每秒通过操作系统进行多达 1000 次传输(中断、下层处理程序、上下文切换、用户回调等)。如果延迟为 16 毫秒,您只需 60 次传输即可处理相同数量的数据,每次传输处理一个更大的块。
在现代多核系统上减少中断计数的用处远不如在单核系统上有用,在单核系统上,所有时间都花在串行(或 USB)中断上意味着处理其他 I/O(例如磁盘传输)时会出现延迟。现在可以将工作分配给多个内核,尽管低效的处理仍然对例如电池寿命。
【讨论】:
您正在查看的功能由供应商的硬件和设备驱动程序专门提供,大多数其他供应商不支持。
RS232C 端口和标准软件 API 没有等效功能。
最好向提供该功能的供应商询问更多信息,例如为什么提供该功能以及如何使用它。
【讨论】:
我一直在为我的串行 Wombat GPIO 扩展器项目编写 Visual C++ 代码。它通过 UART 连接并使用 8 字节数据包进行通信。每个事务需要发送 8 个字节并处理一个 8 个字节的响应。延迟在这里是最重要的,因为处理数据包的速度越快,测量或驱动 IO 的速度就越快。每个中断更多的数据没有帮助,因为它实际上是半双工的。我在 Windows 10 下使用 FTDI 适配器,使用插入时安装的默认驱动程序。对于串行接收,我将超时设置如下:
COMMTIMEOUTS timeouts = { 0 };
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 10;
timeouts.WriteTotalTimeoutMultiplier = 1;
这使得 RX 不等待任何字节进入,只返回可用的字节。然后我反复阅读,直到我有足够的字节来响应 8 字节的响应:
uint8_t buffer[2];
bool result = ReadFile(hSerial, buffer, 1, &dwBytesRead, NULL);
if (dwBytesRead > 0)
{
return(buffer[0]);
}
else
{
return(-1);
}
默认情况下,我看到您在逻辑分析仪上看到的大约 16 毫秒延迟。但是,如果你进入 Windows 设备管理器,选择 FTDI Com 端口的属性,进入端口设置和高级,你会得到这个 gem: FTDI Screen Capture
将延迟计时器更改为 1 毫秒以最大限度地提高响应速度。在逻辑分析仪上看了下结果,果然和预想的一样。
【讨论】: