COM端口上的Win32重叠读取文件返回ERROR_OPERATION_ABORTED

时间:2008-11-20 23:07:14

标签: c++ winapi serial-port

好的,一个关于SO蜂巢的想法...

我的代码直到今天才在许多系统上运行良好,并且部署在许多站点上。它涉及线程从串行端口读取和写入数据。

试图检查一个新设备,我的代码在ReadFile之后调用GetOverlappedResult时遇到了995个ERROR_OPERATION_ABORTED错误。有时阅读会起作用,其他我会得到这个错误。只是忽略错误并重试 - 令人惊讶的是 - 工作时不会丢失任何数据。不需要ClearCommError。

这是片段。

if (!ReadFile(handle,&c,1,&read, &olap))
    {
        if (GetLastError() != ERROR_IO_PENDING)
        {
            logger().log_api(LOG_ERROR,"ser_rx_char:ReadFile");
            throw Exception("ser_rx_char:ReadFile");
        }
    }

    WaitForSingleObjectEx(r_event, INFINITE, true);  // alertable, so, thread can be closed correctly.

    if (GetOverlappedResult(handle,&olap,&read, TRUE) != 0)
    {
        if (read != 1)
            throw Exception("ser_rx_char: no data");

        logger().log(LOG_VERBOSE,"read char %d ( read = %d) ",c, read);
    }
    else
    {
        DWORD err = GetLastError();
        if (err != 995)   //Filters our ERROR_OPERATION_ABORTED
        {
            logger().log_api(LOG_ERROR,"ser_rx_char: GetOverlappedResult");
            throw Exception("ser_rx_char:GetOverlappedResult");
        }
    }

我的第一个猜测是责怪COM端口驱动程序,我之前没有使用它(它是Blackmagic Decklink上的RS422端口,仅供参考),但这感觉就像一个警察。

哦,Vista SP1 Business 32位,为我的罪过。

在我把它归结为“别人的问题”之前,有没有人对可能导致这种情况的原因有任何想法?

2 个答案:

答案 0 :(得分:4)

如何在ReadFile之前设置OVERLAPPED结构? - 我总是将它们归零(显然除了hEvent),这可能是迷信的一部分,但我觉得它在过去引起了我的问题。

我害怕指责驱动程序(如果它不是MS,而不仅仅是参考文献中的微小调整)并非完全不切实际。编写COM驱动程序是一件非常复杂的事情,测试它的难点在于,每个编写的应用程序都使用串行端口和它们的IOCTL略有不同。

另一个常见问题是不要将整个端口设置为 - 例如不调用SetCommTimeouts或SetupComm。我不知道你是否犯了这种错误,但我遇到的人说他们没有使用超时,因为他们实际上意味着他们没有调用SetCommTimeouts所以他们正在使用它们但没有他们的目标是什么......

这种东西可能是第三方COM驱动程序的谋杀案,因为人们经常使用MS驱动程序逃脱任何旧垃圾,并且它并不总是与其他设备一样。

答案 1 :(得分:0)

除了将OVERLAPPED归零之外,你还可以检查你是如何设置olap.hEvent的,也就是说,你对CreateEvent的参数是什么?如果您正在创建一个预先发出信号的事件(即CreateEvent的第三个参数为TRUE),我希望立即返回。此外,不要忘记,如果您将manualReset(CreateEvent的第二个参数)指定为FALSE,GetOverlappedResult()将帮助您清除事件 - 这可以解释为什么它第二次工作。

无法从你的片段中真正判断出这些中的任何一个是否会影响你 - 希望这会有所帮助。