0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

結(jié)構(gòu)體嵌入共聯(lián)體在協(xié)議解析中的技術(shù)性操作過程

嵌入式情報局 ? 來源:最后一個bug ? 2024-02-25 15:00 ? 次閱讀

1、正文部分

1

話題引出

技術(shù)交流群一個小哥貼出了如下圖片 :

73dfcd60-d310-11ee-a297-92fbcf53809c.png ? 73f2f610-d310-11ee-a297-92fbcf53809c.png

問到了共聯(lián)體類型強制轉(zhuǎn)化的問題,當時bug菌點開看到這幾行代碼便產(chǎn)生了莫名的親切感,或許這些就是C語言的魅力所在吧。

其實這種操作在通信協(xié)議中拆包、解包是非常常見的,但是筆者也是在參加工作以后在部門的代碼中g(shù)et到,所以這里整理分享給各位。

2

操作解析

有認真閱讀過筆者公眾號文章的小伙伴,應該在其他文章中也看到過這種操作,不過比較分散,今天抽出來再好好聊聊!

1

buff直接轉(zhuǎn)結(jié)構(gòu)體

74178ab6-d310-11ee-a297-92fbcf53809c.png

上圖是簡單的協(xié)議包,包括幀頭,長度和數(shù)據(jù)部分,在通信數(shù)據(jù)接收或者發(fā)送末端其都位于字節(jié)流中,比如UART通信,最后都是放到Sendbuff[N]或者RecBuff[N],然后發(fā)送出去。

如果你打包好了結(jié)構(gòu)體,然后一個個填充byte到發(fā)送或者接受buff,著實有點麻煩,然而通過結(jié)構(gòu)體指針強制類型轉(zhuǎn)換為uint8_t *pSendBuff;然后在進行字節(jié)流發(fā)送,那就簡潔很多了。

當然在此過程中你還要注意字節(jié)序、對齊等等,在往期的文章中bug菌都有講到,模擬此過程參考下面代碼。

參考示例:

#include
#include

#pragmapack(1)
typedefstruct_tag_Pack
{
intHead;
intLen;
charData[2];
}sPack;

intmain(intargc,char*argv[]){
sPackstSendPack;
sPack*pstRevPack=NULL;
unsignedchar*SendBuff=NULL;
unsignedcharRevBuff[20]={0};
intcnt=0;

//模擬封包
stSendPack.Head=0xFF;
stSendPack.Len=0x08;
stSendPack.Data[0]=0x1;
stSendPack.Data[1]=0x2;

//模擬發(fā)送包
SendBuff=(unsignedchar*)(&stSendPack);

printf("SendData:");
for(cnt=0;cntHead);
printf("pstRevPack.Len=0x%X
",pstRevPack->Len);
printf("pstRevPack.Data[0]=0x%X
",pstRevPack->Data[0]);
printf("pstRevPack.Data[1]=0x%X
",pstRevPack->Data[1]);

printf("
歡迎關(guān)注公眾號:最后一個bug
");
return0;
}

運行結(jié)果:

74285774-d310-11ee-a297-92fbcf53809c.png

2

buff直接轉(zhuǎn)結(jié)構(gòu)共聯(lián)體

743dc596-d310-11ee-a297-92fbcf53809c.png

上一節(jié)我們談到了接受和發(fā)送的buff直接轉(zhuǎn)結(jié)構(gòu)體,然后進行解包處理,而交流群里面圖片中是轉(zhuǎn)共聯(lián)體,可以說這樣的數(shù)據(jù)結(jié)構(gòu)結(jié)合是非常完美的。

buff轉(zhuǎn)結(jié)構(gòu)體類型,就必須buff字節(jié)流里的格式與結(jié)構(gòu)體一致,才能正確的解析,而共聯(lián)體是一種復合類型結(jié)構(gòu),可以存在多種形式的數(shù)據(jù)提取,這樣就可以帶來更多的靈活度,下面代碼在操作一波。

參考示例:

#include
#include

#pragmapack(1)
typedefstruct_tag_PackType1
{
intHead;
intLen;
charData[2];
}sPackType1;

typedefstruct_tag_PackType2
{
intHead;
intLen;
intData[2];
}sPackType2;

typedefstruct_tag_PackType3
{
intHead;
intLen;
floatData[2];
}sPackType3;

//結(jié)構(gòu)共聯(lián)體
typedefunion_tag_PackType
{
sPackType1stPackType1;
sPackType2stPackType2;
sPackType3stPackType3;
}uPackType;

//不同結(jié)構(gòu)體類型的解析函數(shù)
voidParsePackType1(uPackType*punPackType)
{
punPackType->stPackType1.Head=0xF1;
//you do something!
}

voidParsePackType2(uPackType*punPackType)
{
punPackType->stPackType2.Head=0xF2;
//you do something!
}

voidParsePackType3(uPackType*punPackType)
{
punPackType->stPackType3.Head=0xF3;
//you do something!
}
/******************************************
*Fuction:Buff轉(zhuǎn)結(jié)構(gòu)共聯(lián)體
*Author:(公眾號:最后一個bug)
*****************************************/
intmain(intargc,char*argv[]){

uPackType*punPackType;
unsignedcharRevBuff[20]={0};

//通信字節(jié)流接受到RevBuff以后強轉(zhuǎn)
punPackType=(uPackType*)RevBuff;

//根據(jù)自身需要,不同的解析函數(shù),統(tǒng)一傳遞共聯(lián)體即可
ParsePackType1(punPackType);
ParsePackType2(punPackType);
ParsePackType3(punPackType);

printf("
歡迎關(guān)注公眾號:最后一個bug
");
return0;
}

以上就是今天的全部內(nèi)容,enjoy!





審核編輯:劉清

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7614

    瀏覽量

    137412
  • uart通信
    +關(guān)注

    關(guān)注

    0

    文章

    19

    瀏覽量

    7012

原文標題:結(jié)構(gòu)體嵌入共聯(lián)體在協(xié)議解析中的技術(shù)性操作~

文章出處:【微信號:嵌入式情報局,微信公眾號:嵌入式情報局】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    手動移液器的使用操作過程

    手動移液器的使用操作過程  手動移液器常見于臨床試驗和實驗室試驗,不同類型的移液器操作過程也有所不同,下面具體的解析一下?! ∫弧⑹褂梅椒ǎ骸 ?.根據(jù)所需取液量選擇相應移液器及吸液
    發(fā)表于 11-20 11:51

    電路板手工焊接操作過程

    `哪位大神可以分享電路板手工焊接的操作過程嗎?`
    發(fā)表于 02-29 15:14

    求ATmega168看門狗復位的具體操作過程

    ATmega168看門狗復位的具體操作過程
    發(fā)表于 11-18 07:17

    千萬注意!纖薄器件操作過程中損壞不得

    千萬注意!纖薄器件操作過程中損壞不得
    發(fā)表于 04-29 06:29

    怎樣去操作FTS-300光纜普查儀?操作過程中有哪些常見問題?

    FTS-300光纜普查儀的測試原理FTS-300光纜普查儀的功能應用范圍怎樣去操作FTS-300光纜普查儀?操作過程中有哪些常見問題?
    發(fā)表于 05-06 09:42

    C語言的平臺操作過程

    兩種學習C語言的平臺操作過程,在后續(xù)內(nèi)容學習需要熟練應用。這兩種方式分別為:keil c51編程軟件+硬件調(diào)試平臺臺,,keilkeil c51c51編程軟件編程軟件+ proteusproteus軟件...
    發(fā)表于 07-20 06:19

    STM32內(nèi)部FLASH操作過程

    一般說STM32內(nèi)部FLASH就是指主存儲器區(qū)域?qū)憙?nèi)部FLASH操作過程解鎖在對FLASH寫數(shù)據(jù)之前,需要先給解鎖,因為芯片為了防止誤操作修改應用程序,復位之后會給控制寄存器FLASH_CR上鎖(1
    發(fā)表于 12-09 06:37

    GPIO輸入完成按鍵掃描的操作過程是怎樣的

    GPIO輸入完成按鍵掃描的操作過程是怎樣的
    發(fā)表于 02-08 07:29

    RT-Thread操作系統(tǒng)從開機到關(guān)機的操作過程是怎樣的?

    RT-Thread操作系統(tǒng)從開機到關(guān)機的操作過程是怎樣的?
    發(fā)表于 02-15 07:43

    無鉛焊接在操作過程中的常見問題

    無鉛焊接在操作過程中的常見問題目前,電子制造正處于從有鉛向無鉛焊接過渡的特殊階段,無論從環(huán)保、立法、市場競爭和產(chǎn)品可靠等方面來看,無鉛
    發(fā)表于 04-07 17:09 ?1080次閱讀

    心電監(jiān)護儀操作過程

    心電監(jiān)護儀是醫(yī)院實用的精密醫(yī)學儀器,能同時監(jiān)護病人的動態(tài)心電圖形、呼吸、體溫、等生理參數(shù)。這里提供了心電監(jiān)護儀操作過程使用維護。
    發(fā)表于 12-21 17:36 ?2.1w次閱讀
    心電監(jiān)護儀<b class='flag-5'>操作過程</b>

    關(guān)于SMT貼片機操作過程中的注意事項

    SMT貼片機操作過程中的注意事項 SMT貼片機是SMT整線線最關(guān)鍵、最核心的設(shè)備,貼片機是否正常工作直接影響貼片廠的產(chǎn)線運轉(zhuǎn)情況,因此平時的生產(chǎn)過程中,必須要勤加保養(yǎng),讓貼片機發(fā)揮
    發(fā)表于 07-07 15:11 ?4430次閱讀

    FPGA應用中部分重配置的操作過程

    Partial Reconfiguration(部分重配置)現(xiàn)在的FPGA應用中越來越常見,我們這次的教程以Project模式為例來說明部分重配置的操作過程
    的頭像 發(fā)表于 07-05 15:28 ?3767次閱讀
    FPGA應用中部分重配置的<b class='flag-5'>操作過程</b>

    在線快速修復終聚釜攪拌器軸磨損的現(xiàn)場操作過程

    在線快速修復終聚釜攪拌器軸磨損的現(xiàn)場操作過程
    發(fā)表于 12-06 15:17 ?5次下載

    磐石測控:深圳扭轉(zhuǎn)試驗機操作過程是什么樣的?

    磐石測控:深圳扭轉(zhuǎn)試驗機操作過程是什么樣的?
    的頭像 發(fā)表于 10-20 11:17 ?710次閱讀
    磐石測控:深圳扭轉(zhuǎn)試驗機<b class='flag-5'>操作過程</b>是什么樣的?