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的主要内容,如果未能解决你的问题,请参考以下文章
CompileAssemblyFromSource 返回错误“编译表达式:无法打开 c:\Users\*”以读取 'c:\Users\* 不是有效的 Win32 资源文件