0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

嵌入式开发中组包的过程和解析的过程一样吗

Dp1040 来源:玩点嵌入式 2023-08-08 09:12 次阅读

嵌入式产品开发中,我们经常会遇到两个设备之间的通信、设备与服务器的通信、设备和上位机的通信等,很多时候通信协议都是自定义的,所以这就涉及到自定义协议的解析和组包问题。

比如针对下面的这样一个协议:

帧头1 帧头2 字段1 字段2 校验
固定值:0x55 固定值:0xAA 设备ID 电压值 前面所有数据异或值
char char short float char
1字节 1字节 2字节 4字节 1字节

数据在发送时涉及到一个大小端的概念,大小端是针对多字节数据的传输,比如上述协议中字段1,假设两字节内容为0x0001,先发送0x01后发送0x00,称为小端模式;先发送0x00后发送0x01,称为大端模式。

假设字段1内容为0x001,字段2内容为0x40533333(对应为3.3)

假设按照小端方式发送,下面是帧数据:

55 AA 01 00 33 33 53 40 ED

下面来看看如何解析:

若干年前,在第一次面对这种问题时,用的如下傻瓜式的代码方式实现:

#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

简单来说就是硬来,按照数组的先后顺序逐个重组解析,如果协议比较长,代码里会充斥着很多的数组下标,一不小心就数错了。而且如果更改协议的话,代码要改动很多地方。

后来有人告诉我可以定义个结构体,然后使用memcpy函数直接复制过去就完事了。

#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;
}

嗯,的确是方便了很多。不过,该方式仅适合小端传输方式。

再后来,又见到有人用如下代码实现:

#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< len; i++ )
            *(p+i) = *(source + *index + len - i - 1);
    }
    else
    {
        for( i = 0; i < len; i++ )
            *(p+i) = *(source + *index + i);
    }


    *result = *((short*)p);

    *index += len;
}

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


    if(Endianflag == 1 )
    {
        for( i = 0; i < len; i++ )
            *(p+i) = *(source + *index + len - i - 1);
    }
    else
    {
        for( i = 0; i < len; i++ )
            *(p+i) = *(source + *index + i);
    }


    *result = *((float*)p);

    *index += len;
}
该方法既可以支持小端模式,也可以支持大端模式,使用起来也是比较方便。

除了上述2个函数,完整的转换包含以下函数,就是将Bytes转换为不同的数据类型,以及将不同的数据类型转换为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

组包的过程和解析的过程正好相反,这里不再赘述。你在开发中遇到这种问题时,又是如何处理的呢?欢迎留言讨论!

责任编辑:彭菁

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5091

    文章

    19176

    浏览量

    307259
  • 通信协议
    +关注

    关注

    28

    文章

    911

    浏览量

    40412
  • 数据
    +关注

    关注

    8

    文章

    7134

    浏览量

    89478
  • 服务器
    +关注

    关注

    12

    文章

    9295

    浏览量

    85962
  • 嵌入式开发
    +关注

    关注

    18

    文章

    1035

    浏览量

    47677

原文标题:嵌入式开发中,自定义协议的解析与组包

文章出处:【微信号:玩点嵌入式,微信公众号:玩点嵌入式】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    嵌入式开发linux awk命令深度详解

    在我们初学嵌入式开发的时候,总会出现个问题。那就是C语言和嵌入式C编程有什么区别?而嵌入式工程师般都会告诉你,其区别在于
    的头像 发表于 09-20 09:58 4253次阅读

    嵌入式开发入门之旅

    嵌入式开发这个技术新领域,让学员领略嵌入式技术的魅力,使学员对嵌入式开发过程个大致的了解,了解嵌入式开发所需要的知识及学习方法,加强学员
    发表于 07-09 16:57

    嵌入式开发入门之旅

    、文件系统制作与移植、图形化Linux应用程序的开发入门这几个角度,将学员带入嵌入式开发这个技术新领域,让学员领略嵌入式技术的魅力,使学员对嵌入式开发过程
    发表于 07-10 15:59

    浅析基于linux的嵌入式开发

    嵌入式开发的第三个阶段,也是步入复杂的嵌入式系统开发的开始。之所以打算把自己每天的学习经过记录下来,方面是为了做记录方便随时看,加深记忆,最重要的还是由于我自己怕自己在这个
    发表于 11-05 06:49

    嵌入式开发调试经验分享

    嵌入式开发过程中点调试经验嵌入式开发最麻烦的在现场调试过程中或实际运营过程中出现问题很难定位。我在实际
    发表于 11-05 08:15

    嵌入式产品的研发过程是怎样的

    嵌入式产品与普通电子产品一样,在开发过程中需要遵循些基本过程,即从需求分析到总体设计,详细设计到最终产品完成的
    发表于 12-17 08:18

    嵌入式开发自定义协议的解析相关案例分享

    1、嵌入式开发自定义协议的解析  在嵌入式产品开发
    发表于 10-27 17:01

    嵌入式开发

    嵌入式开发就是指在嵌入式操作系统下进行开发嵌入式Linux是以Linux为基础的嵌入式作业系统。这里提供了
    发表于 12-20 13:21
    <b class='flag-5'>嵌入式开发</b>

    嵌入式开发语言有哪些_最全面嵌入式开发语言概述

    嵌入式开发语言有哪些?嵌入式开发的入门门槛还是比较高的,不仅要懂较底层软件,对软件专业水平要求较高,而且必须懂得硬件的工作原理,嵌入式系统应用越来越广泛,目前,在嵌入式系统
    发表于 01-29 14:47 9878次阅读
    <b class='flag-5'>嵌入式开发</b>语言有哪些_最全面<b class='flag-5'>嵌入式开发</b>语言概述

    嵌入式开发):嵌入式开发新手入门

    本篇文章整理下嵌入式开发些入门的基础技能,都是根据以往的工程经验整理,适用于之前没做过嵌入式开发的新手。嵌入式开发流程般如下,
    发表于 10-14 10:58 79次下载
    <b class='flag-5'>嵌入式开发</b>(<b class='flag-5'>一</b>):<b class='flag-5'>嵌入式开发</b>新手入门

    嵌入式开发前景怎么嵌入式开发有哪些优势?

    前景到底怎么呢?具备哪些优势呢?起了解下。对于嵌入式开发行业来说市场上开始有比较大的需求了,但是面临着问题就是市场上嵌入式行业的人才缺
    发表于 10-20 14:50 2次下载
    <b class='flag-5'>嵌入式开发</b>前景怎么<b class='flag-5'>样</b>?<b class='flag-5'>嵌入式开发</b>有哪些优势?

    嵌入式开发资料免费分享

    嵌入式开发资料免费分享嵌入式工程师经验分享:如何学习嵌入式开发截取文档部分学习嵌入式工程师经验分享的资料分享给大家,文档上从、嵌入式系统的概
    发表于 10-21 11:07 47次下载
    <b class='flag-5'>嵌入式开发</b>资料免费分享

    嵌入式开发培训怎么嵌入式开发培训多少钱

    嵌入式人才的工作环境与发展前景也有优势。想学习嵌入式开发培训怎么?可以学好吗?如果你想进入嵌入式开发培训,那么你现在就可以去找个靠谱的
    发表于 11-02 18:06 12次下载
    <b class='flag-5'>嵌入式开发</b>培训怎么<b class='flag-5'>样</b>?<b class='flag-5'>嵌入式开发</b>培训多少钱

    嵌入式开发过程中点调试经验

    嵌入式开发过程中点调试经验嵌入式开发最麻烦的在现场调试过程中或实际运营过程中出现问题很难定位。我在实际
    发表于 11-02 18:06 15次下载
    <b class='flag-5'>嵌入式开发过程中</b>的<b class='flag-5'>一</b>点调试经验

    嵌入式开发前景怎么

    嵌入式开发前景非常广阔,这主要得益于物联网、人工智能、大数据等技术的快速发展,以及嵌入式系统在各个领域的广泛应用。以下是对嵌入式开发前景的详细分析
    的头像 发表于 07-10 09:00 2881次阅读
    <b class='flag-5'>嵌入式开发</b>前景怎么<b class='flag-5'>样</b>?