GetQueuedCompletionStatus停止读取串行端口

时间:2009-09-11 06:49:46

标签: c++ windows

我有一个通过串口生成消息的设备。当我重启设备时,IO完成端口停止读取字节。

代码是调用GetQueuedCompletionStatus():

BOOL bRet = GetQueuedCompletionStatus(
        m_hCompletionPort, 
        &dwBytesTransferred, 
        &dwCompletionKey, 
        &pOverlapped, 
        INFINITE);

PortMon看起来像:

...
IRP_MJ_WRITE    Serial1    SUCCESS     LENGTH: 7    REBOOT.
IRP_MJ_READ     Serial1    CANCELLED   LENGTH: 1    

记录显示以下结果:

bRet=true, dwBytesTransferred=7, pOverlapped=0x0202B028, GetLastError()=997
(sleep forever)

有没有办法检测到此故障并重新建立通信?

我可以监控热节拍并关闭/重新打开串口,但是Windows API允许串行通信以这种方式静默丢弃似乎不对。

3 个答案:

答案 0 :(得分:1)

如果您为打开的串行端口的句柄执行WaitForSingleObject以开始读取数据,那么在重启设备时是否会显示句柄信号?也许这是一种告诉您何时需要再次打开端口的方法?

答案 1 :(得分:1)

IO完成端口当然可以毫无问题地处理这种情况。您无需关闭并重新打开设备。

在这种情况下最可能出现的问题是你在线路上有一个错误(由设备复位引起)你还没有使用ClearCommError()清除。

您需要事先为您的设备使用SetCommState()和SetCommTimeouts()。在DCB中传递给SetCommState(),您需要设置fAbortOnError。如果你确实出错了,你需要在重新排列另一个读取之前调用ClearCommError()。

答案 2 :(得分:1)

RE:janm(我似乎无法在你的回答中添加评论抱歉)

我尝试设置各种标志,包括DCB的fAbortOnError,但GetQueuedCompletionStatus()仍会无限期等待。我还尝试定期超时,并检查串口是否有错误。串口总是看起来很好,但断开连接仍会永久性地破坏IO完成端口。设备重启可能会创建一个瞬态错误状态...我可能会说,因为我从来没有能够检测到它!

一位开发人员也对这个问题有所了解,他们也失败了。所以我们只是重写了代码以使用重叠的串口读取,现在它工作正常。

可能有某些东西,我们错过了某个地方......最后,我们浪费了更多的时间来解决这个谜团而不是重写代码。