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

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

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

嵌入式開(kāi)發(fā)中組包的過(guò)程和解析的過(guò)程一樣嗎

Dp1040 ? 來(lái)源:玩點(diǎn)嵌入式 ? 2023-08-08 09:12 ? 次閱讀

嵌入式產(chǎn)品開(kāi)發(fā)中,我們經(jīng)常會(huì)遇到兩個(gè)設(shè)備之間的通信、設(shè)備與服務(wù)器的通信、設(shè)備和上位機(jī)的通信等,很多時(shí)候通信協(xié)議都是自定義的,所以這就涉及到自定義協(xié)議的解析和組包問(wèn)題。

比如針對(duì)下面的這樣一個(gè)協(xié)議:

幀頭1 幀頭2 字段1 字段2 校驗(yàn)
固定值:0x55 固定值:0xAA 設(shè)備ID 電壓值 前面所有數(shù)據(jù)異或值
char char short float char
1字節(jié) 1字節(jié) 2字節(jié) 4字節(jié) 1字節(jié)

數(shù)據(jù)在發(fā)送時(shí)涉及到一個(gè)大小端的概念,大小端是針對(duì)多字節(jié)數(shù)據(jù)的傳輸,比如上述協(xié)議中字段1,假設(shè)兩字節(jié)內(nèi)容為0x0001,先發(fā)送0x01后發(fā)送0x00,稱(chēng)為小端模式;先發(fā)送0x00后發(fā)送0x01,稱(chēng)為大端模式。

假設(shè)字段1內(nèi)容為0x001,字段2內(nèi)容為0x40533333(對(duì)應(yīng)為3.3)

假設(shè)按照小端方式發(fā)送,下面是幀數(shù)據(jù):

55 AA 01 00 33 33 53 40 ED

下面來(lái)看看如何解析:

若干年前,在第一次面對(duì)這種問(wèn)題時(shí),用的如下傻瓜式的代碼方式實(shí)現(xiàn):

#include

intmain()
{
unsigned char Rxbuf[9]={0x55,0xAA,0x01,0x00,0x33,0x33,0x53,0x40,0xED};

short DeviceId;
floatVoltage;

unsigned char check=0;
int i;

for(i=0;i<8;i++)
????{
????????check?^=?Rxbuf[i];
????}

????if(Rxbuf[0]==0x55?&&?Rxbuf[1]==0xAA?&&?Rxbuf[8]==check?)
????{
????????DeviceId=(Rxbuf[3]<<8)|Rxbuf[2];
????????Voltage=?*((float?*)&Rxbuf[4]);

????????printf("DeviceId:%d
",DeviceId);
????????printf("Voltage:%f
",Voltage);
????}

????return?0;
}
9fcfbe42-3583-11ee-9e74-dac502259ad0.png

簡(jiǎn)單來(lái)說(shuō)就是硬來(lái),按照數(shù)組的先后順序逐個(gè)重組解析,如果協(xié)議比較長(zhǎng),代碼里會(huì)充斥著很多的數(shù)組下標(biāo),一不小心就數(shù)錯(cuò)了。而且如果更改協(xié)議的話(huà),代碼要改動(dòng)很多地方。

后來(lái)有人告訴我可以定義個(gè)結(jié)構(gòu)體,然后使用memcpy函數(shù)直接復(fù)制過(guò)去就完事了。

#include
#include
#pragma pack(1)
struct RxFrame
{
unsigned char header1;
unsigned char header2;
short deviceId;
floatvoltage;
unsigned char check;
};


intmain()
{
unsigned char Rxbuf[9]={0x55,0xAA,0x01,0x00,0x33,0x33,0x53,0x40,0xED};

struct RxFrame RxData;

unsigned char check=0;
int i;

for(i=0;i<8;i++)
????{
????????check?^=?Rxbuf[i];
????}

????memcpy(&RxData,Rxbuf,sizeof(Rxbuf));

????if(Rxbuf[0]==0x55?&&?Rxbuf[1]==0xAA?&&?RxData.check==check?)
????{
????????printf("DeviceId:%d
",RxData.deviceId);
????????printf("Voltage:%f
",RxData.voltage);
????}

????return?0;
}

嗯,的確是方便了很多。不過(guò),該方式僅適合小端傳輸方式。

再后來(lái),又見(jiàn)到有人用如下代碼實(shí)現(xiàn):

#include
#include"convert.h"

intmain()
{
unsigned char Rxbuf[9]={0x55,0xAA,0x01,0x00,0x33,0x33,0x53,0x40,0xED};

short DeviceId;
floatVoltage;

unsigned char check=0;
int i;
int index=0;

for(i=0;i<8;i++)
????{
????????check?^=?Rxbuf[i];
????}

????if(Rxbuf[0]==0x55?&&?Rxbuf[1]==0xAA?&&?Rxbuf[8]==check?)
????{
????????index?+=?2;
????????ByteToShort(Rxbuf,?&index,?&DeviceId);
????????ByteToFloat(Rxbuf,?&index,?&Voltage);

????????printf("DeviceId:%d
",DeviceId);
????????printf("Voltage:%f
",Voltage);
????}

????return?0;
}
其中convert.h如下:

#ifndef CONVERT_H
#define CONVERT_H

voidShortToByte(unsigned char*dest,int*index,short value);
voidFloatToByte(char*dest,int*index,floatvalue);

#endif//CONVERT_H
convert.c如下:
#include"convert.h"
#include
#include

static bool Endianflag=0;

void ByteToShort(const unsigned char*source,int*index,short*result)
{
int i,len=sizeof(short);
char p[len];
memset(p,0,len);

if(Endianflag==1)
{
for(i=0;i
該方法既可以支持小端模式,也可以支持大端模式,使用起來(lái)也是比較方便。

除了上述2個(gè)函數(shù),完整的轉(zhuǎn)換包含以下函數(shù),就是將Bytes轉(zhuǎn)換為不同的數(shù)據(jù)類(lèi)型,以及將不同的數(shù)據(jù)類(lèi)型轉(zhuǎn)換為Bytes。

#ifndef CONVERT_H
#define CONVERT_H

voidByteToShort(const unsigned char*source,int*index,short*result);
voidByteToInt(unsigned char*source,int*index,int*result);
voidByteToLong(char*source,int*index,long long*result);
voidByteToFloat(unsigned char*source,int*index,float*result);
voidByteToDouble(unsigned char*source,int*index,double*result);
voidByteToString(unsigned char*source,int*index,char*result,int length);


voidShortToByte(unsigned char*dest,int*index,short value);
voidIntToByte(char*dest,int*index,int value);
voidLongToByte(char*dest,int*index,long long value);
voidFloatToByte(char*dest,int*index,floatvalue);
voidDoubleToByte(unsigned char*dest,int*index,double value);
voidStringToByte(char*dest,int*index,int length,char*value);

#endif//CONVERT_H

組包的過(guò)程和解析的過(guò)程正好相反,這里不再贅述。你在開(kāi)發(fā)中遇到這種問(wèn)題時(shí),又是如何處理的呢?歡迎留言討論!

責(zé)任編輯:彭菁

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

    關(guān)注

    5087

    文章

    19152

    瀏覽量

    306391
  • 通信協(xié)議
    +關(guān)注

    關(guān)注

    28

    文章

    899

    瀏覽量

    40349
  • 數(shù)據(jù)
    +關(guān)注

    關(guān)注

    8

    文章

    7102

    瀏覽量

    89271
  • 服務(wù)器
    +關(guān)注

    關(guān)注

    12

    文章

    9253

    瀏覽量

    85741
  • 嵌入式開(kāi)發(fā)

    關(guān)注

    18

    文章

    1033

    瀏覽量

    47631

原文標(biāo)題:嵌入式開(kāi)發(fā)中,自定義協(xié)議的解析與組包

文章出處:【微信號(hào):玩點(diǎn)嵌入式,微信公眾號(hào):玩點(diǎn)嵌入式】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    嵌入式開(kāi)發(fā)linux awk命令深度詳解

    在我們初學(xué)嵌入式開(kāi)發(fā)的時(shí)候,總會(huì)出現(xiàn)個(gè)問(wèn)題。那就是C語(yǔ)言和嵌入式C編程有什么區(qū)別?而嵌入式工程師般都會(huì)告訴你,其區(qū)別在于
    的頭像 發(fā)表于 09-20 09:58 ?4242次閱讀

    嵌入式開(kāi)發(fā)入門(mén)之旅

    嵌入式開(kāi)發(fā)這個(gè)技術(shù)新領(lǐng)域,讓學(xué)員領(lǐng)略嵌入式技術(shù)的魅力,使學(xué)員對(duì)嵌入式開(kāi)發(fā)過(guò)程個(gè)大致的了解,了解嵌入式開(kāi)發(fā)所需要的知識(shí)及學(xué)習(xí)方法,加強(qiáng)學(xué)員
    發(fā)表于 07-09 16:57

    嵌入式開(kāi)發(fā)入門(mén)之旅

    、文件系統(tǒng)制作與移植、圖形化Linux應(yīng)用程序的開(kāi)發(fā)入門(mén)這幾個(gè)角度,將學(xué)員帶入嵌入式開(kāi)發(fā)這個(gè)技術(shù)新領(lǐng)域,讓學(xué)員領(lǐng)略嵌入式技術(shù)的魅力,使學(xué)員對(duì)嵌入式開(kāi)發(fā)過(guò)程
    發(fā)表于 07-10 15:59

    淺析基于linux的嵌入式開(kāi)發(fā)

    嵌入式開(kāi)發(fā)的第三個(gè)階段,也是步入復(fù)雜的嵌入式系統(tǒng)開(kāi)發(fā)的開(kāi)始。之所以打算把自己每天的學(xué)習(xí)經(jīng)過(guò)記錄下來(lái),方面是為了做記錄方便隨時(shí)看,加深記憶,最重要的還是由于我自己怕自己在這個(gè)
    發(fā)表于 11-05 06:49

    嵌入式開(kāi)發(fā)調(diào)試經(jīng)驗(yàn)分享

    嵌入式開(kāi)發(fā)過(guò)程中點(diǎn)調(diào)試經(jīng)驗(yàn)嵌入式開(kāi)發(fā)最麻煩的在現(xiàn)場(chǎng)調(diào)試過(guò)程中或?qū)嶋H運(yùn)營(yíng)過(guò)程中出現(xiàn)問(wèn)題很難定位。我在實(shí)際
    發(fā)表于 11-05 08:15

    嵌入式產(chǎn)品的研發(fā)過(guò)程是怎樣的

    嵌入式產(chǎn)品與普通電子產(chǎn)品一樣,在開(kāi)發(fā)過(guò)程中需要遵循些基本過(guò)程,即從需求分析到總體設(shè)計(jì),詳細(xì)設(shè)計(jì)到最終產(chǎn)品完成的
    發(fā)表于 12-17 08:18

    嵌入式開(kāi)發(fā)自定義協(xié)議的解析相關(guān)案例分享

    1、嵌入式開(kāi)發(fā)自定義協(xié)議的解析  在嵌入式產(chǎn)品開(kāi)發(fā)
    發(fā)表于 10-27 17:01

    嵌入式開(kāi)發(fā)

    嵌入式開(kāi)發(fā)就是指在嵌入式操作系統(tǒng)下進(jìn)行開(kāi)發(fā),嵌入式Linux是以L(fǎng)inux為基礎(chǔ)的嵌入式作業(yè)系統(tǒng)。這里提供了
    發(fā)表于 12-20 13:21
    <b class='flag-5'>嵌入式開(kāi)發(fā)</b>

    嵌入式開(kāi)發(fā)語(yǔ)言有哪些_最全面嵌入式開(kāi)發(fā)語(yǔ)言概述

    嵌入式開(kāi)發(fā)語(yǔ)言有哪些?嵌入式開(kāi)發(fā)的入門(mén)門(mén)檻還是比較高的,不僅要懂較底層軟件,對(duì)軟件專(zhuān)業(yè)水平要求較高,而且必須懂得硬件的工作原理,嵌入式系統(tǒng)應(yīng)用越來(lái)越廣泛,目前,在嵌入式系統(tǒng)
    發(fā)表于 01-29 14:47 ?9860次閱讀
    <b class='flag-5'>嵌入式開(kāi)發(fā)</b>語(yǔ)言有哪些_最全面<b class='flag-5'>嵌入式開(kāi)發(fā)</b>語(yǔ)言概述

    嵌入式開(kāi)發(fā)):嵌入式開(kāi)發(fā)新手入門(mén)

    本篇文章整理下嵌入式開(kāi)發(fā)些入門(mén)的基礎(chǔ)技能,都是根據(jù)以往的工程經(jīng)驗(yàn)整理,適用于之前沒(méi)做過(guò)嵌入式開(kāi)發(fā)的新手。嵌入式開(kāi)發(fā)流程般如下,
    發(fā)表于 10-14 10:58 ?79次下載
    <b class='flag-5'>嵌入式開(kāi)發(fā)</b>(<b class='flag-5'>一</b>):<b class='flag-5'>嵌入式開(kāi)發(fā)</b>新手入門(mén)

    嵌入式開(kāi)發(fā)前景怎么?嵌入式開(kāi)發(fā)有哪些優(yōu)勢(shì)?

    前景到底怎么呢?具備哪些優(yōu)勢(shì)呢?起了解下。對(duì)于嵌入式開(kāi)發(fā)行業(yè)來(lái)說(shuō)市場(chǎng)上開(kāi)始有比較大的需求了,但是面臨著問(wèn)題就是市場(chǎng)上嵌入式行業(yè)的人才缺
    發(fā)表于 10-20 14:50 ?2次下載
    <b class='flag-5'>嵌入式開(kāi)發(fā)</b>前景怎么<b class='flag-5'>樣</b>?<b class='flag-5'>嵌入式開(kāi)發(fā)</b>有哪些優(yōu)勢(shì)?

    嵌入式開(kāi)發(fā)般流程

    主流的嵌入式平臺(tái)有三種:ARM平臺(tái)、DSP平臺(tái)和FPGA平臺(tái)。嵌入式產(chǎn)品,與普通電子產(chǎn)品一樣開(kāi)發(fā)過(guò)程都需要遵循些基本的流程,都是
    發(fā)表于 10-21 10:36 ?4次下載
    <b class='flag-5'>嵌入式開(kāi)發(fā)</b><b class='flag-5'>一</b>般流程

    嵌入式開(kāi)發(fā)培訓(xùn)怎么?嵌入式開(kāi)發(fā)培訓(xùn)多少錢(qián)

    ,嵌入式人才的工作環(huán)境與發(fā)展前景也有優(yōu)勢(shì)。想學(xué)習(xí)嵌入式開(kāi)發(fā)培訓(xùn)怎么?可以學(xué)好嗎?如果你想進(jìn)入嵌入式開(kāi)發(fā)培訓(xùn),那么你現(xiàn)在就可以去找個(gè)靠譜的
    發(fā)表于 11-02 18:06 ?12次下載
    <b class='flag-5'>嵌入式開(kāi)發(fā)</b>培訓(xùn)怎么<b class='flag-5'>樣</b>?<b class='flag-5'>嵌入式開(kāi)發(fā)</b>培訓(xùn)多少錢(qián)

    嵌入式開(kāi)發(fā)過(guò)程中點(diǎn)調(diào)試經(jīng)驗(yàn)

    嵌入式開(kāi)發(fā)過(guò)程中點(diǎn)調(diào)試經(jīng)驗(yàn)嵌入式開(kāi)發(fā)最麻煩的在現(xiàn)場(chǎng)調(diào)試過(guò)程中或?qū)嶋H運(yùn)營(yíng)過(guò)程中出現(xiàn)問(wèn)題很難定位。我在實(shí)際
    發(fā)表于 11-02 18:06 ?15次下載
    <b class='flag-5'>嵌入式開(kāi)發(fā)過(guò)程中</b>的<b class='flag-5'>一</b>點(diǎn)調(diào)試經(jīng)驗(yàn)

    嵌入式開(kāi)發(fā)前景怎么?

    嵌入式開(kāi)發(fā)前景非常廣闊,這主要得益于物聯(lián)網(wǎng)、人工智能、大數(shù)據(jù)等技術(shù)的快速發(fā)展,以及嵌入式系統(tǒng)在各個(gè)領(lǐng)域的廣泛應(yīng)用。以下是對(duì)嵌入式開(kāi)發(fā)前景的詳細(xì)分析
    的頭像 發(fā)表于 07-10 09:00 ?2801次閱讀
    <b class='flag-5'>嵌入式開(kāi)發(fā)</b>前景怎么<b class='flag-5'>樣</b>?