主页
  • README
  • 主页
  • journal日记
    • rtthreadv5.1.0
  • embedded嵌入式开发
    • SSPI
    • fsm状态机
      • 事件驱动型状态机
    • mm_fifo环形队列
    • lvgl
      • font字体生成
    • 经验分享
      • Byte alignment and protocol parsing
  • rt-thread笔记
    • repo
    • 线程
    • 设备
      • 串口
  • openharmony笔记
  • scons笔记
  • 公共基础库
    • 嵌入式utils
    • 鸿蒙utils
  • 开发与部署
    • gitbook
    • gitea服务器
      • gitea官方指导部署
      • Bitnami部署
    • 让Linux磁盘空间的弹性管理
    • docker笔记
      • docker
      • container
      • docker-compose
      • docker-machine
      • Portainer可视化界面
    • 1Panel运维管理面板
      • 家庭云的公网访问
      • 1Panel快速配置TCP代理
      • 端口转发访问内网
    • 服务器推荐
    • 极路由3刷机
    • ipv6公网
    • ddns动态域名
    • nginx反向代理
    • jumpserver堡垒机
    • bt宝塔
    • service自启服务
    • cloudreve部署
    • proxy代理
  • 工具收集
    • git笔记
      • git-push
      • git-flow
      • git-svn
      • EWARM
      • 常见需求
    • UsbEAm Hosts Editor
    • keil_下载地址
    • iar_下载地址
  • 相关链接
    • gitee首页
    • github首页
    • B站首页
    • gitea仓库备份
    • blog地址
Powered by GitBook
On this page
  • 前言
  • 示例场景
  • 使用示例
  1. embedded嵌入式开发
  2. 经验分享

Byte alignment and protocol parsing

#pragma pack(show) //显示当前内存对齐的字节数,编辑器默认8字节对齐

#pragma pack(n) //设置编辑器按照n个字节对齐,n可以取值1,2,4,8,16

#pragma pack(push) //将当前的对齐字节数压入栈顶,不改变对齐字节数

#pragma pack(push,n) //将当前的对齐字节数压入栈顶,并按照n字节对齐

#pragma pack(pop) //弹出栈顶对齐字节数,不改变对齐字节数

#pragma pack(pop,n) //弹出栈顶并直接丢弃,按照n字节对齐

前言

擅长用字节对齐可以节省脑细胞,提高代码可读性,这里为大家展示下配置字节对齐来高效的解析报文。

示例场景

如下报文格式

字节
类型
功能
说明

CMD

0x10

SCMD

0x10

2 1 1 4 1 4 [4] …

U16 U8 U8 Float U8 Float [Float] …

Type Chnnl State Value Num AD1 [AD2] …

数据 1 的测量状态和测量值: Type:表示数据类型,详见附录 B。 Chnnl:表示数据通道 State:表示数据状态 b7:数值有效/无效:1-有效,0-无效 b6b3:为 0,预留 b2b0:数值单位,详见附录 B。 Value:表示数据测量值 Num:电参量个数 AD1:对应实测电参量 1 AD2:对应实测电参量 2 …:对应实测点参量 n

[2] [1] [1] [4] [1] [4] [4] …

[U16] [U8] [U8] [Float] [U8] [Float] [Float] …

Type Chnnl State Value Num AD1 [AD2] …

数据 2 的测量状态和测量值:

…

…

数据 n 的测量状态和测量值:

对应报文可以如下设计

#pragma pack(1)
typedef struct _PROTOCOL_0X1010
{
    uint16_t type;
    uint8_t chnnl;
    uint8_t state;
    float value;
    uint8_t num;
    float AD[0];
} protocol_0x1010_t;

#pragma pack()

关键信息解释:

  1. #pragma pack(1) 与 #pragma pack() 是成对出现的,否则将影响后续其它结构体的对齐问题,这里进行1字节对齐,牺牲了MCU的效率换来的是可读取,而牺牲的效率我认为比我们手动操作强的多。

  2. AD[0] 柔性数组,在结构体中可以方便对后续数据的读取工作,AD多个参数便可之间访问,避免类型转换问题。

使用示例

        uint32_t i = 0;
        while (i <= pfrm->length)
        {
            protocol_0x1010_ptr data_ptr = (protocol_0x1010_ptr) & (pfrm->text[i]);
            uint8_t sensor_idx = sensor_info_find_idx(data_ptr->type);
            if (sensor_idx < DEV_MAX_ID)
            {
                sensor_value_t *sensor_value_ptr = &m_sensor_module.value[sensor_idx];
                sensor_value_ptr->status.online = (data_ptr->state & 0x80) != 0;
                sensor_value_ptr->tick = tick_cur;
                sensor_value_ptr->meas = data_ptr->value;
                sensor_value_ptr->raw = data_ptr->AD[0];
                i += sizeof(protocol_0x1010_t) + data_ptr->num * sizeof(float);
            }

        }
Previous经验分享Nextrt-thread笔记

Last updated 1 year ago