Linux串列埠select傳送接收位不對齊問題

2021-06-23 00:43:20 字數 801 閱讀 8375

最近做乙個串列埠和fpga通訊的程式,linux環境下,使用select+read去讀取串列埠。在使用的過程中開始總是提示接收的資料有誤。一直沒有去仔細核對過read讀取的資料長度。才導致了這個問題的產生。

select其實只能監控串列埠fd檔案的寫入變化,不能監控到是否寫入了合格位元組數。比如我串列埠傳送端傳送了10個位元組,而select很可能在fd接收到1個位元組時就已經檢測到了,而等待read去讀取的時候,串列埠傳送端只寫入了8個位元組的,這個時候,假如你不判斷read讀取返回位元組數,那你接收到的資料肯定是不完整的。

解決方案有兩個:

1、延時。假如你串列埠設定115200的波特率,那麼你可以算算,傳輸乙個位,你需要8.6μs,10bit(8個資料位+1個stop+1個開始bit)就是86μs,10個位元組你再乘以10你就能算出來了,期間可以忽略cpu的指令週期耗時,太短了。我使用的usleep()這個系統呼叫。

2、每次讀取乙個位元組,讓read迴圈讀取,直到達到預期的位元組數為止,因為read是阻塞的,會一直等待串列埠資料,read的fd指標會根據每次讀取的結果往後移,沒有資料是不會後移的,所以,你不用關心,已經讀取過的位元組是否會影響。不放心你可以做個試驗便知。

方案2中比方案一中的好處是顯而易見的,假如你讀取的資料量非常大,而且,非常的密集。吞吐量也相當大,建議使用第二種方案,因為10位元組,你就可以在乙個read週期內節省下1ms,對於cpu你可以幹很多事情了。當然2中也會造成資料處理的麻煩,因為是單位元組的,後期可能造成的問題,是相當多的。所以,在沒有相當複雜的功能面前,建議使用第一種方式。追求完美的,可以考慮第二種。

其實,這裡講的是串列埠收發的安全性,select+read是存在安全問題的。

select串列埠通訊

開始也不怎麼了解select,查了很多資料以後,才稍微用了起來 串列埠的初始化,配置波特率,資料位,校驗位等等 這裡只貼出了,select的簡單用法,後面是 傳送函式 檢測效果是 效果是 接收到了之後,把串列埠線拔了,超過了時間,然後break,列印while迴圈結束之後的main函式裡的hel 標...

串列埠傳送資料

s 串列埠程式設計 詳解4 串列埠傳送資料 串列埠傳送資料報括 十六進製制傳送資料 手動傳送資料 自動傳送資料 手動傳送資料的 如下 cpp view plain copy 手動傳送 long tx count 0 void cscommdlg onbuttonmanualsend else els...

ARMlinux串列埠傳送

首先選擇串列埠 位置方便,不和串列埠終端重合,定義char 為串列埠節點目錄 dev tty ttysac3 char uart3 dev ttysac3 然後定義乙個傳送資料buffer char buffer hello world n 開啟串列埠,呼叫配置函式set opt 自己定義的 if ...