使用ReadFile延迟串口设备

时间:2018-01-20 12:16:41

标签: windows serial-port

我需要在REALTIME(< = 5 ms)的Windows上读取串行端口设备(每秒发送数据)的数据。但ReadFile的时间成本是不可预测的,这让我变得疯狂。部分代码可以在以下位置找到: https://gist.github.com/morris-stock/62b1674b4cda0e9df84d4738e54773f8

延迟被转储到https://gist.github.com/morris-stock/62b1674b4cda0e9df84d4738e54773f8#file-serialport_win-cc-L283

    Poco::Timestamp now;
    if (!ReadFile(_handle, buffer, size, &bytesRead, NULL))
        throw Poco::IOException("failed to read from serial port");

    Poco::Timestamp::TimeDiff elapsed = now.elapsed();
    std::cout << Poco::DateTimeFormatter::format(now, "%Y-%m-%d %H:%M:%S.%i")
              << ", elapsed: " << elapsed << ", data len: " << bytesRead << std::endl << std::flush;

有时ReadFile费用大约为3000美元(可能会受COMMTIMEOUTS影响),但有时会花费15600美元(不受COMMTIMEOUTS影响)。

如果我能做些什么来解决问题,请告诉我。

P.S。

COMMTIMEOUTS

COMMTIMEOUTS cto;
cto.ReadIntervalTimeout         = 1;
cto.ReadTotalTimeoutConstant    = 1;
cto.ReadTotalTimeoutMultiplier  = 0;
cto.WriteTotalTimeoutConstant   = MAXDWORD;
cto.WriteTotalTimeoutMultiplier = 0;

主要阅读主题部分:

https://gist.github.com/morris-stock/62b1674b4cda0e9df84d4738e54773f8#file-serialdevice-cc-L31

设备数据类型

baudrate :9600,它每秒发送大约400个字节(连续,然后在剩下的时间内没有数据)。

consle输出

      wPacketLength: 64
     wPacketVersion: 2
      dwServiceMask: 1
        dwReserved1: 0
       dwMaxTxQueue: 0
       dwMaxRxQueue: 0
          dwMaxBaud: 268435456
      dwProvSubType: 1
 dwProvCapabilities: 255
   dwSettableParams: 127
     dwSettableBaud: 268959743
      wSettableData: 15
wSettableStopParity: 7943
   dwCurrentTxQueue: 0
   dwCurrentRxQueue: 68824
        dwProvSpec1: 0
        dwProvSpec2: 1128813859
         wcProvChar: 0039F16C
2018-01-22 03:35:52.658, elapsed: 15600, data len: 0
2018-01-22 03:35:52.673, elapsed: 15600, data len: 0
2018-01-22 03:35:52.689, elapsed: 15600, data len: 0
2018-01-22 03:35:52.704, elapsed: 15600, data len: 0
2018-01-22 03:35:52.720, elapsed: 15600, data len: 0
2018-01-22 03:35:52.736, elapsed: 15600, data len: 0
2018-01-22 03:35:52.751, elapsed: 15600, data len: 0

1 个答案:

答案 0 :(得分:0)

就我而言,重要的是Windows system clock resolution

ClockRes给了我:

C:\work\utils\ClockRes>Clockres.exe

Clockres v2.1 - Clock resolution display utility
Copyright (C) 2016 Mark Russinovich
Sysinternals

Maximum timer interval: 15.600 ms
Minimum timer interval: 0.500 ms
Current timer interval: 1.000 ms

C:\work\utils\ClockRes>Clockres.exe

Clockres v2.1 - Clock resolution display utility
Copyright (C) 2016 Mark Russinovich
Sysinternals

Maximum timer interval: 15.600 ms
Minimum timer interval: 0.500 ms
Current timer interval: 15.600 ms

通过在我的应用启动时调用timeBeginPeriod(1),我可以获得更一致的结果。

感谢大家的亲切帮助。