2008-11-20 80 views
2

好,一個是SO蜂羣思維...上COM端口的Win32重疊READFILE歸國ERROR_OPERATION_ABORTED

我有有碼 - 直到今天 - 運行在許多系統上就好了,並部署在許多網站。它涉及從串口讀取和寫入數據的線程。

試圖檢出一個新設備,我的代碼被淹沒了995個ERROR_OPERATION_ABORTED錯誤,在ReadFile之後調用GetOverlappedResult。有時閱讀會起作用,othertimes我會得到這個錯誤。只是忽略錯誤而重試會令人吃驚 - 在不丟失任何數據的情況下工作。不需要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位,爲我的罪過。

在我把這個問題放在「別人的問題」之前,有沒有人有任何想法可能會導致這種情況?

+1

我不認爲這是你的問題,但你沒有正確使用`WaitForSingleObjectEx`。您應該檢查(1)`dwWait == WAIT_OBJECT_0`或(2)`dwWait == WAIT_TIMEOUT && dwError == ERROR_IO_PENDING`。 – jww 2012-09-20 17:56:27

回答

4

如何在ReadFile之前設置OVERLAPPED結構? - 我總是將它們清零(顯然除了事件之外),這可能是迷信的一部分,但我有一種感覺,那就是過去給我造成了問題。

我害怕責怪司機(如果它不是MS,而不是僅僅從參考中微調)並不是完全不現實的。編寫COM驅動程序是一件非常複雜的事情,測試它的困難在於,每一個應用程序都使用串行端口及其IOCTLs略有不同。

另一個常見問題不是設置整個端口 - 例如不調用SetCommTimeouts或SetupComm。我不知道你是否犯了這種錯誤,但我遇到了那些說他們沒有使用超時的人,因爲他們實際上並沒有調用SetCommTimeouts,所以他們使用它們,但沒有一個概念他們設置...

這種東西可以謀殺第三方COM驅動程序,因爲人們經常與MS驅動程序的任何舊廢話逃脫,它並不總是與其他設備一樣工作。

+0

我同意超時看起來像一個可能的原因,特別是因爲沒有輸入丟失,ReadFile調用一次只讀取一個字節。但是,如果應用程序正確設置了端口,則責怪驅動程序,包括MS驅動程序是否真實。 – 2008-11-20 23:49:50

0

除了將OVERLAPPED歸零之外,您還可以檢查您是如何設置olap.hEvent的,也就是說,您的CreateEvent參數是什麼?如果您正在創建一個預先發送的事件(即CreateEvent的第三個參數爲TRUE),我會期待立即返回。另外,不要忘記,如果您將manualReset(CreateEvent的第二個參數)指定爲FALSE,則GetOverlappedResult()將幫助您清除該事件 - 這可能解釋了爲什麼它第二次運行。

無法真正告訴你的代碼是否影響到你 - 希望這有助於你。