Linux串列埠接收最佳化——針對modbus協議

在Linux下編寫Modbus協議的串列埠接收驅動時,之前看過幾種其他實現方式,但都不理想。以下提出一種實現方式,經工程應用後發現比較簡單可靠,並且穩定。

Modbus協議串列埠接收實現方式的主要思路是:

(1) 當前串列埠有接收資料,開始計時;

(2) 如果一定時間內,串列埠又有接收資料,則重新開始計時;

(3) 如果一定時間後,串列埠沒有接收資料,則認為上一幀接收完畢。

透過查閱資料得知,Linux有API函式能夠隨時查詢串列埠上當前可讀取的位元組數,所以對處理串列埠接收及幀間隔的邏輯進行簡化,流程圖如圖1所示。

Linux串列埠接收最佳化——針對modbus協議

圖1 Linux下modbus接收處理邏輯

對應的程式程式碼如圖2所示。

#elif (COM_READ_STYLE_SELECT == COM_READ_STYLE_WAIT) int nread1, nread2; ioctl(com_fd_using, FIONREAD, &nread1);//獲取串列埠當前可讀取的位元組數 if(nread1 > 0)//如果位元組數大於0 { usleep(RECV_FRAME_TIME_INTERVAL * 1000);//延時一定時間,取決於幀間隔 ioctl(com_fd_using, FIONREAD, &nread2);//再次獲取串列埠當前可讀取的位元組數 if(nread2 == nread1)//如果兩次位元組數一樣,說明系統底層已接收完一個完整資料幀 { nread1 = nread2 > datalength ? datalength : nread2;//取可用位元組數和要讀取位元組數中的較小者 nread2 = read(com_fd_using, data, nread1);//從系統底層讀取串列埠接收資料 return nread2;//返回實際讀取的位元組數 } else { return 0;//如果兩次位元組數不一樣,說明系統底層還未接收完一個完整資料幀,則返回0 } } else { return 0;//如果沒有可讀取資料,則返回0 }#endif

圖2 Linux下modbus接收處理程式碼

該方法已經在工程實踐中驗證過,簡單可靠,並且穩定。

如需要原始碼及測試例程,可聯絡我獲取。