當(dāng)前位置:首頁 > 公眾號精選 > C語言編程
[導(dǎo)讀]0.前言作為一名嵌入式工程師,經(jīng)常需要通過UART與外設(shè)打交道,而對于串行總線來說,往往我們必須要進(jìn)行幀同步。通常的做法是把信令包含在2個0x7E的中間。除此之外還有HDLC、PPP等協(xié)議也會到有此應(yīng)用場景。那么如何從這些數(shù)據(jù)幀中提取有效數(shù)據(jù)呢?本文通過一個簡單的實(shí)例給大家詳細(xì)講...


0. 前言

作為一名嵌入式工程師,經(jīng)常需要通過UART與外設(shè)打交道,而對于串行總線來說,往往我們必須要進(jìn)行幀同步。通常的做法是把信令包含在2個0x7E的中間。

除此之外還有HDLC、PPP等協(xié)議也會到有此應(yīng)用場景。

那么如何從這些數(shù)據(jù)幀中提取有效數(shù)據(jù)呢?

本文通過一個簡單的實(shí)例給大家詳細(xì)講述如何從幀中提取有效的協(xié)議信令。

1. 幀格式要求

首先我們明確下幀提取的一些要求:

  • (1)把信息字段中出現(xiàn)的每一個0x7E字節(jié)轉(zhuǎn)變?yōu)?字節(jié)序列(0x7D,0x5E)。
  • (2)若信息字段中出現(xiàn)一個0x7D的字節(jié)(即出現(xiàn)了和轉(zhuǎn)義字符一樣的比特組合),則把轉(zhuǎn)義字符0x7D轉(zhuǎn)變?yōu)?字節(jié)序列(0x7D,0x5D)。

舉例:一個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ù),則反過來。

2. 設(shè)計(jì)

  1. 底層傳上來的每一短幀長度不固定
  2. 底層傳上來的每一短幀7e頭位置不固定,可能有可能沒有,可能有1個7e也可能有2個7e
  3. 默認(rèn)每一幀數(shù)據(jù)最多2個7e
比如:我們從底層收上來的原始數(shù)據(jù)幀格式如下:那么我們要能夠提取兩個7e之間的協(xié)議數(shù)據(jù)幀,同時還原幀中的所有的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)如下

測試代碼如下:

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("************測試hdlc_send()******************\n");

?len?=?hdlc_send(data1,6);

?printf("********************end**********************\n\n");
#endif
?printf("\n************測試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é)果如下:

注意

本代碼仍然有一些bug,暫時沒有修改,所以實(shí)際項(xiàng)目慎用。小心數(shù)組越界??!

完整代碼鏈接:

鏈接:https://pan.baidu.com/s/1rPEDC3erLpPRH0OnkfNH_A

提取碼:wzxq


版權(quán)申明:內(nèi)容來源網(wǎng)絡(luò),版權(quán)歸原創(chuàng)者所有。除非無法確認(rèn),都會標(biāo)明作者及出處,如有侵權(quán),煩請告知,我們會立即刪除并致歉!


本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
關(guān)閉
關(guān)閉