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

Posted

技术标签:

【中文标题】COM 端口上的 Win32 重叠读取文件返回 ERROR_OPERATION_ABORTED【英文标题】:Win32 Overlapped Readfile on COM Port returning ERROR_OPERATION_ABORTED 【发布时间】:2008-11-20 23:07:14 【问题描述】:

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

我的代码 - 直到今天 - 在许多系统上都可以正常运行并部署在许多站点上。它涉及线程从串行端口读取和写入数据。

尝试检查新设备时,我的代码在 ReadFile 之后调用 GetOverlappedResult 时出现 995 ERROR_OPERATION_ABORTED 错误。有时读取会起作用,有时我会收到此错误。只需忽略错误并重试即可 - 令人惊讶的是 - 不会丢失任何数据。不需要 ClearCommError。

这是sn-p。

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 位,我的罪过。

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

【问题讨论】:

我不认为这是你的问题,但你没有正确使用WaitForSingleObjectEx。您应该检查 (1) dwWait == WAIT_OBJECT_0 或 (2) dwWait == WAIT_TIMEOUT && dwError == ERROR_IO_PENDING 【参考方案1】:

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

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

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

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

【讨论】:

我同意超时看起来是一个可能的原因,特别是因为没有输入丢失并且 ReadFile 调用一次只读取一个字节。但是,如果应用程序正确设置了端口,那么责怪驱动程序是很现实的,包括它是否是 MS 的驱动程序。 我正在清除 OVERLAPPED 结构(除了 hEvent)并在 COMMTIMEOUTS 中的所有字段中调用 SetCommTimeouts,并将其设为零。我尝试更改为非重叠 i/o 并得到相同的结果。是时候尝试另一个通讯端口了...【参考方案2】:

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

无法从您的 sn-p 中真正判断出这些是否会影响您 - 希望这会有所帮助。

【讨论】:

以上是关于COM 端口上的 Win32 重叠读取文件返回 ERROR_OPERATION_ABORTED的主要内容,如果未能解决你的问题,请参考以下文章

WinSock 异步I/O模型-4

CompileAssemblyFromSource 返回错误“编译表达式:无法打开 c:\Users\*”以读取 'c:\Users\* 不是有效的 Win32 资源文件

转载使用Win32API实现Windows下异步串口通讯

UDP.6.重叠IO模型:完成例程

从 STM32 Nucleo-F767ZI [Ubuntu] 中的 USB 虚拟 COM 读取数据

如何杀win32.parite.b病毒?