2012-06-14 63 views
0

我在Java中從串口讀取數據時遇到了一個奇怪的問題。Java串口IO讀取

我已經通過在其中工作的罰款線程輪詢方法來讀取串口數據,但我有一個要求,我需要將數據寫入到串行端口和讀回ACK。將數據寫入串口是成功的,但我無法讀回數據。這裏有兩個讀取操作,一個在主線程中,另一個在主線程中。

一旦我接收串行寫入數據我暫停其從串行端口使用標誌讀取數據的線程,並開始再次一次寫入完成串口讀取數據,但我無法讀取數據。我寫操作後禁止讀取串口,並啓用線程讀取串口的線程,這裏我看到串口的ACK數據。

任何可以建議是怎麼回事錯這個串行讀操作?它不是緩衝讀/寫操作。

+0

我不確定我遵循你的邏輯。你好像你一次從三個不同的線索閱讀,這聽起來不是一個好主意。 – gobernador

+0

它不是三個不同的線程,而是兩個線程,一個線程輪詢連續讀取,另一個線程在主線程中讀取,只有當它執行寫操作時纔讀取 –

+1

雖然我仍然不知道這個原因,但我相信我理解問題。我相信他是說主線程發送一個寫命令,並且有一個讀(ACK-Checker),之後應該看到一個ACK,並且在另一個線程(讓我們稱之爲「一般閱讀器」)中讀取一個讀做每一個其他的閱讀操作。問題似乎是,當他從主線程寫入時,該ACK檢查器沒有看到ACK。如果他禁用了「ACK-checker」,那麼「通用閱讀器」在進行正常輪詢(通常不應該)時會看到ACK。它是否正確? – Xantham

回答

0

我強烈建議只使用一個專用線程來訪問串口讀取。最可靠的解決方案曾經是一箇中斷處理程序,將所有接收到的數據剷除到線程安全狀態機。嘗試從多個線程讀取串行端口會導致問題。串口IO不關心你「暫停了你的線程」,由於上下文切換,數據可能已經被獲取並丟失。

所以乾脆繼續讀什麼進來,如果ACK預期並獲得通過旗語通知主線程。在一個骯髒殘酷簡化的僞代碼:

主線程循環:

{ 
    serialReaderThread.isAckExpected = true 
    sendWriteCommand(); 
    ackReceivedSemaphore.wait(); 
} 

串行讀線程循環:

{ 
    readData(); 
    if(isAckExpected && data == ack) { 
    mainThread.ackReceivedSemaphore.notify(); 
    isAckExpected = false 
    } 
} 

您需要發送的寫命令之前設置isAckExpected,因爲如果你的串行同行速度足夠快,您甚至可以在sendWriteCommand甚至返回之前獲得迴應。

+0

感謝Vvtmarin:實際上它只是在我爲讀取串行數據創建的線程上,我將主線程稱爲程序啓動或創建線程(主線程) –

0

您不應該嘗試從串口讀取不同的線程。正確的架構是讓單線程完成讀取,並通過多個隊列將傳入數據分發給感興趣的客戶端。

你將不得不由讀線程給出的數據是「正常的讀取處理」線程。當您需要執行寫入/確認序列時,正在執行寫入/確認的線程會臨時將自己註冊到讀取線程並轉移數據流。

你仍然需要處理數據的任何交織(即寫入請求之後,但在接收到ACK接收正常的數據),但最多也就是你的應用程序。