2010-08-10 118 views
0

我在寫一個C程序,它可以讀取和寫入串行端口。每次寫入後都會進行一次讀取,其中包含基於寫入的數據。我將有大約16種不同的寫入來執行,每個寫入之後都是讀取。使用串口讀取和寫入C

我對串行編程還很陌生,並且試圖確定如何處理這個問題。程序是否應該在每次寫入/讀取期間阻塞(基本上有很長時間(1)的寫入和讀取循環)?

是否有可能讓一個線程發送寫入,而另一個線程執行讀取?是否可以創建一個回調讓線程知道數據何時可以從串口讀取?

感謝您的幫助。

編輯:

操作系統:Linux

+1

what os?在Windows/Linux呢? – obelix 2010-08-10 18:55:08

+0

您的串行接口是雙面的嗎? – NickHalden 2010-08-10 18:55:46

+1

您需要指定操作環境。串行端口在C中沒有標準化,影響正確答案的功能因系統而異。 – Darron 2010-08-10 18:56:10

回答

1

這聽起來像一個簡單的循環與讀取和寫入就足夠了。如果你想要更多的控制(比如在X秒沒有輸入的情況下寫保持活動),使用selectpoll;它們允許你「感知」數據是否可用,所以read不會阻塞(但是,如果在選擇和讀取之間發生什麼情況,你仍應該閱讀非阻塞)。多線程在這種情況下沒有意義。

selectpoll還允許您測試寫入是否會阻止;再次,寫無阻塞只是爲了確保。除了selectpoll之外,你通常不希望你的進程掛在某個阻塞系統調用中,也就是說。 (至少我沒有)

使用ioctl來設置串口線上的各種參數。使用

$ strace -o /tmp/strace.minicom -f minicom 

要啓動minicom(或任何其他終端程序),並查看他們如何處理事情,如果您卡住了。和往常一樣,請參閱man select/poll/read/ioctl瞭解更多信息。

0

有幾種方法可以解決這個問題。最好的選擇可能取決於您讀取串行端口時要查看的數據類型以及您想要如何處理該數據中的錯誤。

拳頭方法是打開串口文件阻止IO做:

while (question) { 
    write(ser_fd, question.data, question.len); 
    sleep(1); 
    ioctl(ser_fd, FIONREAD, &answer.len); 
    answer.data = realloc(answer.data, answer.len); 
    read(ser_fd, question.answer, question.answer_len); 
    question = next(question); 
    answer = next(answer); 
} 

雖然我沒有做任何錯誤在此處理。

如果您希望能夠超時等待回覆來到串口,那麼這會改變很多事情。您應該考慮使用select,pselect,poll,ppoll或系統調用的epoll系列。這些允許程序阻止(睡眠),直到有數據準備好讀入。然後,您可以循環查詢並閱讀,直到您完成答案或耗盡時間。

另一種選擇是嘗試使用SIGIO,但我不建議這樣做。要做到這一點並且很難調試並不容易。

此外,您可能可以使用SIGALRM將您從閱讀調用中取消,以充當超時。

如果您嘗試使用stdio輸入和輸出例程,那麼這是非常困難的。你會被困在第一種方法之類的東西里,而不能詢問有多少數據已經準備好。

相關問題