COM 端口延迟的有用性
Usefulness of COM port latency
如您在本教程中所见,COM 端口的默认延迟计时器为 16 毫秒。
COM Port Latency
但在大多数情况下,我们希望延迟时间最小。
在互联网上我们看到很多关于为什么这个值应该越小越好的解释,但是从来没有选择一个大的值。
那么为什么默认值是 16 毫秒,而它可能是 1 毫秒?
以更大的块传输数据更 CPU 高效。如果您有 1 毫秒的延迟,您的串行端口可能会通过 OS(中断、下层处理程序、上下文切换、用户回调等)导致每秒传输多达 1000 次。如果延迟为 16 毫秒,您只需 60 次传输即可处理相同数量的数据,每次传输处理一个更大的块。
减少中断计数在现代多核系统上的用处远不如在单核上,在单核系统上,所有时间都花在串行(或 USB)中断上意味着处理其他 I/O 这样的延迟作为磁盘传输。现在可以将工作分配给多个内核,但低效的处理仍然会对例如计算机产生不良影响。电池寿命。
您正在查看的功能由供应商的硬件和设备驱动程序专门提供,大多数其他供应商不支持。
RS232C 端口和标准软件 API 没有等效功能。
最好向提供它的供应商询问更多信息,例如为什么提供该功能以及如何使用它。
我一直在为我的 Serial Wombat GPIO 扩展器项目编写 Visual C++ 代码。它通过 UART 连接并使用 8 字节数据包进行通信。每个事务需要发送 8 个字节并处理一个 8 字节的响应。这里的延迟是最重要的,因为处理数据包的速度越快,进行测量或驱动 IO 的速度就越快。每个中断的更多数据无济于事,因为它实际上 half-duplex。我在 Windows 10 下使用 FTDI 适配器,使用插入时安装的默认驱动程序。对于串行接收,我设置超时如下:
COMMTIMEOUTS timeouts = { 0 };
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 10;
timeouts.WriteTotalTimeoutMultiplier = 1;
这使得 RX 不等待任何字节进入,只有 return 可用的字节。然后我反复阅读,直到我有足够的字节用于 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 毫秒以最大化响应速度。在逻辑分析仪上看了下结果,完全符合预期。
如您在本教程中所见,COM 端口的默认延迟计时器为 16 毫秒。
COM Port Latency
但在大多数情况下,我们希望延迟时间最小。
在互联网上我们看到很多关于为什么这个值应该越小越好的解释,但是从来没有选择一个大的值。
那么为什么默认值是 16 毫秒,而它可能是 1 毫秒?
以更大的块传输数据更 CPU 高效。如果您有 1 毫秒的延迟,您的串行端口可能会通过 OS(中断、下层处理程序、上下文切换、用户回调等)导致每秒传输多达 1000 次。如果延迟为 16 毫秒,您只需 60 次传输即可处理相同数量的数据,每次传输处理一个更大的块。
减少中断计数在现代多核系统上的用处远不如在单核上,在单核系统上,所有时间都花在串行(或 USB)中断上意味着处理其他 I/O 这样的延迟作为磁盘传输。现在可以将工作分配给多个内核,但低效的处理仍然会对例如计算机产生不良影响。电池寿命。
您正在查看的功能由供应商的硬件和设备驱动程序专门提供,大多数其他供应商不支持。
RS232C 端口和标准软件 API 没有等效功能。
最好向提供它的供应商询问更多信息,例如为什么提供该功能以及如何使用它。
我一直在为我的 Serial Wombat GPIO 扩展器项目编写 Visual C++ 代码。它通过 UART 连接并使用 8 字节数据包进行通信。每个事务需要发送 8 个字节并处理一个 8 字节的响应。这里的延迟是最重要的,因为处理数据包的速度越快,进行测量或驱动 IO 的速度就越快。每个中断的更多数据无济于事,因为它实际上 half-duplex。我在 Windows 10 下使用 FTDI 适配器,使用插入时安装的默认驱动程序。对于串行接收,我设置超时如下:
COMMTIMEOUTS timeouts = { 0 };
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 10;
timeouts.WriteTotalTimeoutMultiplier = 1;
这使得 RX 不等待任何字节进入,只有 return 可用的字节。然后我反复阅读,直到我有足够的字节用于 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 毫秒以最大化响应速度。在逻辑分析仪上看了下结果,完全符合预期。