ReadFile串口设备延迟不一致

问题描述 投票:0回答:1

我需要在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 us(这可以,受COMMTIMEOUTS影响)返回,但有时,它需要15600美元(不受COMMTIMEOUTS的影响)。

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

附:

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

设备数据类型

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

控制台输出

      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
windows serial-port
1个回答
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),我可以获得更一致的结果。

感谢大家的亲切帮助。

© www.soinside.com 2019 - 2024. All rights reserved.