🤖 roboto_origin_03 Wiki
首页 / IMU 子模块 / 超核私有协议解码

超核(HiPNUC)私有协议是 HiPNUC 系列 IMU/INS 模块在串口链路中使用的二进制通信格式,与 CAN 总线上的 J1939、CANopen 协议并列,承担将传感器原始字节流解析为结构化数据的职责。本页聚焦 hipnuc_dec 解码器的实现原理,涵盖帧同步、CRC 校验、载荷解析、位图可变长包以及上层驱动的集成方式。

Sources: hipnuc_dec.h

协议帧格式与同步机制

一帧数据由 6 字节固定头部和变长载荷组成。头部以同步字 0x5A 0xA5 开头,随后 2 字节小端无符号整型表示载荷长度 len,最后 2 字节为 CRC16 校验值。hipnuc_input 在累积到 CH_HDR_SIZE(6)字节后,从偏移 2 处提取长度,并继续接收直至收齐 CH_HDR_SIZE + len 字节;若 len 超过 HIPNUC_MAX_RAW_SIZE(512),则立即丢弃并重新进入同步等待状态。

字段 偏移 长度(字节) 说明
SYNC1 0 1 固定 0x5A
SYNC2 1 1 固定 0xA5
LENGTH 2 2 载荷长度,小端序
CRC16 4 2 覆盖同步字、长度及载荷
PAYLOAD 6 len 数据载荷,可包含多个子包

Sources: hipnuc_dec.c

字节流状态机

解码器采用逐字节输入的状态机实现流式同步,无需预先分配完整帧缓冲区之外的额外状态变量。sync_hipnuc 内部维护一个双字节滑动窗口,当检测到 0x5A 0xA5 时将 nbyte 置为 2;后续字节顺序填入 hipnuc_raw_t::buf,在收齐头部后校验长度合法性,最终进入解码阶段。该设计保证了解码器在面对丢包、噪声或错序时能够自动恢复同步。

stateDiagram-v2
    [*] --> SYNC_WAIT : 初始 / 帧完成后 nbyte=0
    SYNC_WAIT --> SYNC_WAIT : 未检测到 0x5A 0xA5
    SYNC_WAIT --> HEADER_FILL : 同步头匹配,nbyte=2
    HEADER_FILL --> PAYLOAD_FILL : nbyte == 6 且 len 合法
    HEADER_FILL --> SYNC_WAIT : len > 512 非法
    PAYLOAD_FILL --> DECODE : nbyte >= 6 + len
    DECODE --> SYNC_WAIT : 解析完成,nbyte 清零

Sources: hipnuc_dec.c

CRC16 校验算法

decode_hipnuc 在解析载荷前执行 CRC-16 校验,其生成多项式为 0x1021,与 CCITT 标准兼容。计算范围覆盖头部前 4 字节(同步字 + 长度)以及整个载荷区;计算得到的 2 字节结果与头部偏移 4 处存储的 CRC 值进行比较,若不一致则返回 -1 并丢弃该帧。该逐位移位异或的实现不依赖外部库,具备跨平台可移植性。

Sources: hipnuc_dec.c, hipnuc_dec.c

载荷解析与包类型

通过校验后,parse_data 从载荷首字节开始按标签(Tag)逐段解析。每个标签字节的取值决定后续数据的类型与长度;解码器同时支持 legacy 标签(如 0xA0 加速度、0xB0 陀螺仪、0xD0 欧拉角等)和新版标准包标签(0x910x920x810x83)。Legacy 标签的字段被统一映射到 hi91_t 浮点结构,以兼容旧款 HI226/HI229 设备;多个 legacy 标签可在同一帧内组合出现,逐步填充 hi91_t 的不同字段。例如,0xA0/0xA1 后跟随 6 字节 int16 加速度数据,解码器将其除以 1000 转换为以 g 为单位的浮点数后写入 hi91.acc0xB0/0xB1 陀螺仪数据除以 10 得到 deg/s;0xD0 欧拉角则分别按 0.01°、0.01°、0.1° 的系数解析。

Sources: hipnuc_dec.c

标准数据包结构

新版标准包通过 memcpy 直接映射到对应的 packed 结构体,避免了逐字段手动解包的开销。0x91 为浮点型 IMU 数据包,包含加速度、陀螺仪、磁力计、欧拉角、四元数、气压及温度;0x92 为整型原始数据包,字段类型以 int16/int32 为主,便于在资源受限场景下降低带宽;0x81 为 INS 组合导航包,涵盖 UTC、GNSS 质量、速度、位置等融合结果;0x83 为基于位图的可变长数据包,支持字段的动态裁剪与扩展。所有结构均使用 __attribute__((__packed__)) 修饰,确保内存布局与协议字节流严格一致,杜绝编译器填充字节导致的错位。

Sources: hipnuc_dec.h, hipnuc_dec.c

0x83 可变长包与位图机制

0x83 包的解析最为灵活。载荷前 4 字节固定包含 main_status(2 字节)、ins_status(1 字节)和 data_bitmap(4 字节),随后根据 data_bitmap 的置位情况顺序拼接可选字段。位图掩码从 HI83_BMAP_ACC_B(bit 0)到 HI83_BMAP_GNSS_VEL(bit 31),每个置位对应固定字节长度的数据块;解析器通过局部变量 idx 顺序累加偏移量,实现零拷贝的流式字段定位。需注意的是,当前源码中 0x83 处理块末尾未显式添加 break,执行流将落入紧随其后的 0x92 处理逻辑,阅读或修改时需特别关注该控制流细节。

Sources: hipnuc_dec.h, hipnuc_dec.c

下表汇总了 0x83 位图掩码与对应字段的字节占用:

位图掩码 字段 长度(字节)
HI83_BMAP_ACC_B 0 acc_b[3] (float) 12
HI83_BMAP_GYR_B 1 gyr_b[3] (float) 12
HI83_BMAP_MAG_B 2 mag_b[3] (float) 12
HI83_BMAP_RPY 3 rpy[3] (float) 12
HI83_BMAP_QUAT 4 quat[4] (float) 16
HI83_BMAP_SYSTEM_TIME 5 system_time (uint32) 4
HI83_BMAP_UTC 6 utc 结构体 8
HI83_BMAP_AIR_PRESSURE 7 air_pressure (float) 4
HI83_BMAP_TEMPERATURE 8 temperature (float) 4
HI83_BMAP_INCLINATION 9 inclination[3] (float) 12
HI83_BMAP_HSS 10 hss[3] (float) 12
HI83_BMAP_HSS_FRQ 11 hss_frq[3] (float) 12
HI83_BMAP_VEL_ENU 12 vel_enu[3] (float) 12
HI83_BMAP_ACC_ENU 13 acc_enu[3] (float) 12
HI83_BMAP_INS_LON_LAT_MSL 14 ins_lon_lat_msl[3] (double) 24
HI83_BMAP_GNSS_QUALITY_NV 15 质量与卫星数(4 字节) 4
HI83_BMAP_OD_SPEED 16 od_speed (float) 4
HI83_BMAP_GNSS_LON_LAT_MSL 30 gnss_lon_lat_msl[3] (double) 24
HI83_BMAP_GNSS_VEL 31 gnss_vel[3] (float) 12

Sources: hipnuc_dec.h, hipnuc_dec.c

与驱动层的集成

HipnucIMUDriver 中,串口接收回调 serial_rx_cbk 将每个字节顺序送入 hipnuc_input;当返回值大于 0 表示完整帧解码成功后,驱动从 raw_.hi91 中提取四元数、角速度和加速度,并分别乘以 DEG_TO_RAD(陀螺仪 deg/s → rad/s)与 GRA_ACC(加速度 g → m/s²)转换为标准物理单位,最后写入 sensor_data_。整个过程在 std::unique_lock<std::shared_mutex> 保护下进行,避免与上层 get_quat()get_ang_vel() 等读取接口发生竞态。

Sources: hipnuc_imu_driver.cpp

量纲转换与调试输出

不同数据包在驱动层和日志输出层采用各自的量纲转换系数。hi91 的加速度原始值为 g,需乘 GRAVITY(9.8)得到 m/s²;陀螺仪原始值为 deg/s,乘 DEG_TO_RAD 得到 rad/s。hi92hi81 的整型字段则按固定系数转换,例如 hi81 的位置维度乘 1e-7(度)、速度乘 0.01(cm/s → m/s)。hipnuc_dump_packet 在生成调试字符串时复用了这些系数,将结构化数据格式化为类 JSON 字符串写入外部缓冲区,支持 HI91HI92HI81HI83 四种输出格式,便于在串口接收线程中直接打印或转发到日志系统。

Sources: hipnuc_dec.c, hipnuc_imu_driver.cpp

下一步阅读

理解私有协议解码后,可继续阅读 串口通信与 UART 接收线程 了解字节流如何进入解码器,或 传感器数据访问与线程安全 深入探讨 shared_mutex 的读写策略与数据一致性模型。