7E頭解析的那些事兒(幀格式分析實(shí)例)
0. 前言
作為一名嵌入式工程師,經(jīng)常需要通過(guò)UART與外設(shè)打交道,而對(duì)于串行總線來(lái)說(shuō),往往我們必須要進(jìn)行幀同步。通常的做法是把信令包含在2個(gè)0x7E的中間。
除此之外還有HDLC、PPP等協(xié)議也會(huì)到有此應(yīng)用場(chǎng)景。
那么如何從這些數(shù)據(jù)幀中提取有效數(shù)據(jù)呢?
本文通過(guò)一個(gè)簡(jiǎn)單的實(shí)例給大家詳細(xì)講述如何從幀中提取有效的協(xié)議信令。
1. 幀格式要求
首先我們明確下幀提取的一些要求:
(1)把信息字段中出現(xiàn)的每一個(gè)0x7E字節(jié)轉(zhuǎn)變?yōu)?字節(jié)序列(0x7D,0x5E)。
(2)若信息字段中出現(xiàn)一個(gè)0x7D的字節(jié)(即出現(xiàn)了和轉(zhuǎn)義字符一樣的比特組合),則把轉(zhuǎn)義字符0x7D轉(zhuǎn)變?yōu)?字節(jié)序列(0x7D,0x5D)。
舉例:一個(gè)PPP幀的數(shù)據(jù)部分:
- 7D 5E FE 27 7D 5D 7D 5D 65 7D 5E
那么實(shí)際上真正的數(shù)據(jù)是
- 7E FE 27 7D 7D 65
轉(zhuǎn)換圖解:
同樣的,如果要發(fā)送數(shù)據(jù),則反過(guò)來(lái)。
2. 設(shè)計(jì)
- 底層傳上來(lái)的每一短幀長(zhǎng)度不固定
- 底層傳上來(lái)的每一短幀7e頭位置不固定,可能有可能沒(méi)有,可能有1個(gè)7e也可能有2個(gè)7e
- 默認(rèn)每一幀數(shù)據(jù)最多2個(gè)7e
比如:我們從底層收上來(lái)的原始數(shù)據(jù)幀格式如下:
那么我們要能夠提取兩個(gè)7e之間的協(xié)議數(shù)據(jù)幀,同時(shí)還原幀中的所有的7e。
很顯然我們希望最終解析后結(jié)果如下:
- 7e 0f 0e 30 27 1c 00 27 1c 01 27 1c 02 7e 00 29 7e
- 7e 11 73 7e
- 7e 00 27 1c 01 27 1c 02 7e 00 29 7e
幀解析詳細(xì)設(shè)計(jì)流程圖
3.代碼
不上代碼的就是耍流氓
首先看下如果下發(fā)數(shù)據(jù)幀,如何將所有的7e和7d做替換:函數(shù)hdlc_send(char * data,UINT8 len)實(shí)現(xiàn)如下:
int hdlc_rcv_frm(UINT8 *data,int len)實(shí)現(xiàn)如下
測(cè)試代碼如下:
- int main()
- {
- int len;
- char data1[6]={0x7e,0xf,0xe,0x30,0x27,0x1c};
- char data2[6]={0x0,0x27,0x1c,0x1,0x27,0x1c};
- char data3[8]={0x2,0x7d,0x5e,0x0,0x29,0x7e,0x0,0x7e};
- char data4[6]={0x11,0x73,0x7e,0x30,0x27,0x7e};
- char data5[6]={0x0,0x27,0x1c,0x1,0x27,0x1c};
- char data6[6]={0x2,0x7d,0x5e,0x0,0x29,0x7e};
- #if 0
- printf("************測(cè)試hdlc_send()******************\n");
- len = hdlc_send(data1,6);
- printf("********************end**********************\n\n");
- #endif
- printf("\n************測(cè)試hdlc_rcv_frm()******************\n");
- hdlc_rcv_frm(data1,6);
- hdlc_rcv_frm(data2,6);
- hdlc_rcv_frm(data3,8);
- hdlc_rcv_frm(data4,6);
- hdlc_rcv_frm(data5,6);
- hdlc_rcv_frm(data6,6);
- printf("********************end**************************\n");
- }
- 運(yùn)行結(jié)果如下:
運(yùn)行結(jié)果如下:
注意
本代碼仍然有一些bug,暫時(shí)沒(méi)有修改,所以實(shí)際項(xiàng)目慎用。小心數(shù)組越界啊!
完整代碼鏈接:
鏈接:https://pan.baidu.com/s/1rPEDC3erLpPRH0OnkfNH_A
提取碼:wzxq































