1. 程式人生 > >UART學習筆記二:如何去check資料幀

UART學習筆記二:如何去check資料幀

接著以前的文章(UART學習筆記一),繼續聊聊這個話題。上次的文章分析瞭如果去

接收資料,這章分析下如果去check一幀資料。如果想要check一幀資料,就要考慮兩種情況:

1)資料幀接收完畢,意思就是說buffer裡面有一幀完整的資料;

2)資料幀暫時沒有接收完畢,比如:幀頭、校驗、幀尾,目前只收到了幀頭;

上面兩種情況和底層驅動實現方式直接相關:

1)Timer_out方式;

2)邊接收邊解析,佇列快取方式;

首先來說第一種情況:

底層驅動利用TIMER_OUT方式,這個是時候,check_function(...)可以認為已經收到一幀

“完整”資料。然後就去按著常規的方式去解析:

1)找幀頭,如果成功則執行步驟2,否則丟棄;

2)找幀尾,如果成功則執行步驟三,否則丟棄;

3)檢查校驗,如果成功則通知協議解析,否則丟棄;

如果成功,丟給協議解析函式,否則直接丟棄,並清空快取;

這種方式很簡單,基本沒什麼難度,按著幀格式校驗就可以。

再來看看另外一種:

底層驅動負責入隊操作,check_function負責出隊操作,同時負責檢查,其編寫邏輯就不能

按著上面的步驟直接操作了。要利用狀態機的思維,首先定義出幾個狀態,然後根據狀態去

做相應的事情。

enum{

FSM_START = 0,

FSM_WAIT_HEAD,

FSM_WAIT_TAIL,

FSM_WAIT_USER_READ

};

FSM_START:做一些初始化工作,必須保留。

FSM_WAIT_HEAD:查詢幀頭,其邏輯如下:

如果接收資料 < 幀頭資料個數,把資料儲存到快取,直接返回;

如果沒有找到幀頭,則保留快取區最後的幀頭資料個數-1個數據,其它丟棄,返回;

如果找到幀頭,則直接丟棄幀頭前面資料,同時把幀頭以後資料複製到快取頭開始處

(這是為了處理方便,當然也可以用環形的處理方式),狀態機跳到FSM_WAIT_TAIL。

FSM_WAIT_TAIL:等待幀尾,其邏輯如下:

如果快取資料<計算出的幀長總個數儲存資料,直接返回;

檢驗幀尾,如果錯誤,則丟棄快取第一個位元組,goto到FSM_WAIT_HEAD;

校驗幀校驗位,如果錯誤,則丟棄快取第一個位元組,goto到FSM_WAIT_HEAD;

跳轉到FSM_WAIT_USER_READ:什麼都不幹,不能出隊,也不能對快取進行操作,

就是直接返回 true;(為了做同步)

使用者檢查到true,就會呼叫read_data(。。。)把檢查到一幀資料,拷貝到使用者快取區,

同時自動復位狀態機;

注意點:

1、丟棄快取第一個位元組,goto到FSM_WAIT_HEAD,是為了防止由於上幀資料接收到

一部分(後面的資料丟失),引起下幀資料錯誤問題;

2、最好有個接收超時,然後整幀校驗,復位狀態機;

3、用goto是為了更好的解決邏輯問題,使邏輯更清晰;

有時間再去說說如果去做協議分析。以上觀點都是本人愚見,還請大神們不吝指教。