【问题标题】:Reading from serial port via ReadFile is very slow通过 ReadFile 从串口读取非常慢
【发布时间】:2019-02-18 13:45:20
【问题描述】:

我正在使用 Win32 API 从串口读取数据:

DWORD numRead = 0;
ReadFile(mPortHandle, mReceiveBuffer.get(), mReceiveBufferSize, &numRead, nullptr);

这个调用需要非常长的时间:准确来说需要 129 毫秒(通过 QueryPerformanceCounter 测量)。

我使用几种不同的硬件设备进行了测量:

  • 带有 FTDI 芯片组的 USB 适配器
  • 带有多产芯片组的 USB 适配器
  • PCI express RS232 卡
  • 主板板载串口

这些设备中的每一个都给了我完全相同的延迟:129 毫秒。因此,我不认为它是硬件或驱动程序的错误(每个设备应该使用完全不同的驱动程序,对吧?)。

我也摆弄了超时,但这并没有改变任何东西。

还能是什么?

【问题讨论】:

  • 从串口读取很慢;这并不奇怪。您使用的波特率是多少?
  • 目前我使用的是 115200 Bd。但实际上没有数据进来,所以 ReadFile 返回 0 Bytes。什么都不做仍然需要大约 130 毫秒。
  • @Boris - NtReadFile 真的返回 STATUS_TIMEOUT 我猜如果你有 0 个字节/你需要先设置 COMMTIMEOUTS

标签: winapi serial-port readfile


【解决方案1】:

好的,问题解决了:-)

到目前为止,我将超时设置如下:

COMMTIMEOUTS timeouts;
timeouts.ReadIntervalTimeout = 1;
timeouts.ReadTotalTimeoutMultiplier = 1;
timeouts.ReadTotalTimeoutConstant = 1;
timeouts.WriteTotalTimeoutMultiplier = 1;
timeouts.WriteTotalTimeoutConstant = 1;

不起作用。如果我只设置常量,它可以工作:

COMMTIMEOUTS timeouts;
timeouts.ReadIntervalTimeout = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 1;
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 0;

现在 ReadFile 在 1 毫秒内返回。

【讨论】:

  • 它就像一个魅力!
【解决方案2】:

也许是因为你总是通过指定接收缓冲区的总大小来读取文件。

接收缓冲区是否很大?

如果为DataReceived事件注册了一个事件处理函数,并且只读取到达设备驱动缓冲区的数据,那么额外的等待时间将会减少。

【讨论】:

    猜你喜欢
    • 2021-10-07
    • 2012-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-09
    • 1970-01-01
    • 2019-06-16
    • 2020-11-23
    相关资源
    最近更新 更多