嵌入式硬件通信接口協(xié)議-UART(四)設計起止式的應用層協(xié)議
解析思路是:
本文引用地址:http://m.butianyuan.cn/article/201903/398678.htm1.確保環(huán)形緩沖區(qū)有足夠一個幀結構的數(shù)據(jù)量,否則返數(shù)據(jù)量不足的錯誤;
2.接著讀出一個字節(jié)判斷幀頭標志是否為0x55,否則返幀頭錯誤;
3.再次讀一個字節(jié)作為幀長度數(shù)據(jù),且長度至少3個字節(jié)(2個CRC校驗值+至少1字節(jié)數(shù)據(jù)包),否則返幀長度錯誤;
4.讀出幀長度數(shù)據(jù),如果此時環(huán)形緩沖區(qū)的可讀數(shù)量比長度數(shù)值小,出現(xiàn)這情況的原因可能是幀長度字段在發(fā)送期間出現(xiàn)異常,或是對端設備串口傳輸慢而未完整傳輸一幀,此時可做適當?shù)难訒r等待,如果超時退出,且返幀長度錯誤;
5.繼續(xù)讀出2個字節(jié)作為CRC校驗值,且需要注意先收到的是crc16L,先收到小端數(shù)值;
6.緊接著把數(shù)據(jù)包讀出,此時讀的長度應該是第4步中的幀長度數(shù)據(jù)少2個字節(jié);
7.最后對數(shù)據(jù)包計算一個CRC校驗值,對比接收到的校驗值,校驗值不一致則返錯誤校驗碼。
函數(shù)返回值符合以下枚舉的錯誤碼:
被解析數(shù)據(jù)源
看到這里也許仍有疑問,用于解析的數(shù)據(jù)源哪來?數(shù)據(jù)什么時候被寫進環(huán)形緩沖區(qū)內(nèi)?
參考上一篇《嵌入式硬件通信接口-使用RingBuffer處理數(shù)據(jù)(二)詳細設計過程》介紹的關于向環(huán)形緩沖區(qū)寫入一個字節(jié),但dclib_ringbuffer這個模塊屬于應用庫模塊層,而如果直接把dclib_rb_writebyte這一個接口放在串口接收中斷里執(zhí)行,這就破壞了系統(tǒng)的架構層次,對工程代碼的維護和移植是個麻煩事,因此采用回調函數(shù)的方式。
嵌入式開發(fā)工程師都知道,一般在使用官方的庫時,經(jīng)常會遇到需要自己實現(xiàn)一些回調函數(shù),從而利用注冊接口把回調函數(shù)傳遞給庫或者驅動層,使庫或者驅動層在執(zhí)行時調用該回調函數(shù)。
根據(jù)這個思路,同樣的這里也采用回調函數(shù)的形式,回調函數(shù)內(nèi)完成了把串口接收到的數(shù)據(jù)寫入環(huán)形緩沖區(qū)內(nèi)。
回調函數(shù)的實現(xiàn)源碼截圖:
事實上僅僅調用了dclib_ringbuffer功能里的寫一字節(jié)接口dclib_rb_writebyte,回調函數(shù)傳進來的參數(shù)dat就是串口接收到的數(shù)據(jù)。
有了回調函數(shù),還要把這個回調函數(shù)的地址傳給底層驅動,這也就是常說的“注冊”的過程,注冊接口在固件板級接口層里串口模塊dcbsp_uart實現(xiàn),注冊接口時dclib_uart_callback_reg函數(shù):
又偏題了,關于回調函數(shù)在此不做深入論述。
簡而言之,環(huán)形緩沖區(qū)寫入一字節(jié)的執(zhí)行過程,放在回調函數(shù)里,當串口接收中斷觸發(fā)后,中斷里會根據(jù)注冊的回調函數(shù)地址,進而執(zhí)行回調函數(shù),實現(xiàn)對環(huán)形緩沖區(qū)寫入一個字節(jié)數(shù)據(jù)。如此操作的理由是不改變工程代碼的分層架構,并且便于維護與移植!
為了縮減篇幅,最后貼上測試代碼的部分:
最后也附上調試期間串口打印的解析結果:
起止式幀結構的講解稍有匆忙,篇幅也略大,文中基礎技術要點未能細致講解,后續(xù)統(tǒng)籌規(guī)劃再做單獨介紹!
接下來在此幀結構基礎上,講述如何設計在數(shù)據(jù)包放置應用層的交互指令,敬請期待下回分!
評論