3

好的,一个适合蜂巢思维的人......

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

尝试检查新设备时,我的代码在 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 位,为我的罪过。

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

4

2 回答 2

4

您如何在 ReadFile 之前设置 OVERLAPPED 结构?- 我总是将它们归零(显然 hEvent 除外),这可能是部分迷信,但我有一种感觉,它在过去给我带来了问题。

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

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

这种东西对于 3rd-party COM 驱动程序来说可能是谋杀,因为人们经常使用 MS 驱动程序摆脱任何旧的废话,而且它并不总是与其他设备相同。

于 2008-11-20T23:27:19.277 回答
0

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

无法从您的代码段中真正分辨出这些是否会影响您 - 希望这会有所帮助。

于 2009-05-06T19:34:39.327 回答