嵌入式硬件通信接口協(xié)議-UART(四)設(shè)計起止式的應(yīng)用層協(xié)議
解析思路是:
本文引用地址:http://m.butianyuan.cn/article/201903/398678.htm1.確保環(huán)形緩沖區(qū)有足夠一個幀結(jié)構(gòu)的數(shù)據(jù)量,否則返數(shù)據(jù)量不足的錯誤;
2.接著讀出一個字節(jié)判斷幀頭標(biāo)志是否為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è)備串口傳輸慢而未完整傳輸一幀,此時可做適當(dāng)?shù)难訒r等待,如果超時退出,且返幀長度錯誤;
5.繼續(xù)讀出2個字節(jié)作為CRC校驗值,且需要注意先收到的是crc16L,先收到小端數(shù)值;
6.緊接著把數(shù)據(jù)包讀出,此時讀的長度應(yīng)該是第4步中的幀長度數(shù)據(jù)少2個字節(jié);
7.最后對數(shù)據(jù)包計算一個CRC校驗值,對比接收到的校驗值,校驗值不一致則返錯誤校驗碼。
函數(shù)返回值符合以下枚舉的錯誤碼:

被解析數(shù)據(jù)源
看到這里也許仍有疑問,用于解析的數(shù)據(jù)源哪來?數(shù)據(jù)什么時候被寫進(jìn)環(huán)形緩沖區(qū)內(nèi)?
參考上一篇《嵌入式硬件通信接口-使用RingBuffer處理數(shù)據(jù)(二)詳細(xì)設(shè)計過程》介紹的關(guān)于向環(huán)形緩沖區(qū)寫入一個字節(jié),但dclib_ringbuffer這個模塊屬于應(yīng)用庫模塊層,而如果直接把dclib_rb_writebyte這一個接口放在串口接收中斷里執(zhí)行,這就破壞了系統(tǒng)的架構(gòu)層次,對工程代碼的維護(hù)和移植是個麻煩事,因此采用回調(diào)函數(shù)的方式。
嵌入式開發(fā)工程師都知道,一般在使用官方的庫時,經(jīng)常會遇到需要自己實現(xiàn)一些回調(diào)函數(shù),從而利用注冊接口把回調(diào)函數(shù)傳遞給庫或者驅(qū)動層,使庫或者驅(qū)動層在執(zhí)行時調(diào)用該回調(diào)函數(shù)。
根據(jù)這個思路,同樣的這里也采用回調(diào)函數(shù)的形式,回調(diào)函數(shù)內(nèi)完成了把串口接收到的數(shù)據(jù)寫入環(huán)形緩沖區(qū)內(nèi)。
回調(diào)函數(shù)的實現(xiàn)源碼截圖:

事實上僅僅調(diào)用了dclib_ringbuffer功能里的寫一字節(jié)接口dclib_rb_writebyte,回調(diào)函數(shù)傳進(jìn)來的參數(shù)dat就是串口接收到的數(shù)據(jù)。
有了回調(diào)函數(shù),還要把這個回調(diào)函數(shù)的地址傳給底層驅(qū)動,這也就是常說的“注冊”的過程,注冊接口在固件板級接口層里串口模塊dcbsp_uart實現(xiàn),注冊接口時dclib_uart_callback_reg函數(shù):

又偏題了,關(guān)于回調(diào)函數(shù)在此不做深入論述。
簡而言之,環(huán)形緩沖區(qū)寫入一字節(jié)的執(zhí)行過程,放在回調(diào)函數(shù)里,當(dāng)串口接收中斷觸發(fā)后,中斷里會根據(jù)注冊的回調(diào)函數(shù)地址,進(jìn)而執(zhí)行回調(diào)函數(shù),實現(xiàn)對環(huán)形緩沖區(qū)寫入一個字節(jié)數(shù)據(jù)。如此操作的理由是不改變工程代碼的分層架構(gòu),并且便于維護(hù)與移植!
為了縮減篇幅,最后貼上測試代碼的部分:


最后也附上調(diào)試期間串口打印的解析結(jié)果:

起止式幀結(jié)構(gòu)的講解稍有匆忙,篇幅也略大,文中基礎(chǔ)技術(shù)要點未能細(xì)致講解,后續(xù)統(tǒng)籌規(guī)劃再做單獨介紹!
接下來在此幀結(jié)構(gòu)基礎(chǔ)上,講述如何設(shè)計在數(shù)據(jù)包放置應(yīng)用層的交互指令,敬請期待下回分!
評論