Skip to content

Version1.0.0
Filepyro_crc.hpyro_crc.cpp

PYRo CRC

CRC8 与 CRC16 校验算法实现

该模块提供 RoboMaster 裁判系统协议兼容的 CRC8 与 CRC16 校验/追加函数。采用纯 C(extern "C")导出接口,零堆分配,适用于 ISR 上下文中直接调用。

前置知识:了解 CRC(循环冗余校验)基本原理、查表法实现

Part 1: 代码全解 (Code Deep Dive)

1. 设计特点

  • 无堆分配: 所有查表数据均为编译期常量 static const,无运行时内存开销
  • 纯 C 导出: 使用 extern "C" 包裹,可在 C/C++ 混合项目中直接调用
  • DJI 协议兼容: CRC16 采用 DJI 电调协议规定的多项式与初始值(0xFFFF

2. CRC16

多项式为 0x1189(对应 DJI 协议),初始值 0xFFFF,结果以小端序写入帧尾:

函数作用
verify_crc16_check_sum(p_msg, len)校验帧尾 2 字节 CRC16,返回 1 表示通过
append_crc16_check_sum(p_msg, len)将 CRC16 小端序填入 p_msg[len-2]p_msg[len-1]
c
// 内部查表计算
static uint16_t get_crc16_check_sum(uint8_t const *p_msg, uint16_t len, uint16_t crc16)
{
    while (len--) {
        data = *p_msg++;
        crc16 = (crc16 >> 8) ^ crc16_tab[(crc16 ^ data) & 0x00ff];
    }
    return crc16;
}

调用方需保证缓冲区末尾 2 字节为 CRC 预留空间。verify_* 会对比帧尾值与计算值,append_* 会覆写帧尾。

3. CRC8

多项式 0x5E,初始值 0xFF,结果写入帧尾 1 字节:

函数作用
verify_crc8_check_sum(p_msg, len)校验帧尾 1 字节 CRC8
append_crc8_check_sum(p_msg, len)将 CRC8 填入 p_msg[len-1]

4. 调用约定

输入皆不修改 (verify_* 系列): p_msg 标记为 const
调用方负责缓冲区空间: append_* 系列要求外层保证 p_msglen 字节且末尾 CRC 区域已预留空间
空值保护: p_msg == nullptrlen 过短时返回 0 (false) 或直接返回

Part 2: 快速使用

c
#include "pyro_crc.h"

// 校验整帧 (帧尾 2 字节为 CRC16)
if (verify_crc16_check_sum(frame, total_len)) {
    // CRC16 通过,数据完 整
}

// 帧头 CRC8 校验
if (verify_crc8_check_sum(header, 5)) {
    // 帧头通过
}

// 组帧:先写数据段(留出帧尾),再追加 CRC
uint8_t tx_frame[64];
tx_frame[0] = 0xA5;
// ... 填充数据 ...
append_crc16_check_sum(tx_frame, sizeof(tx_frame));  // 覆写末尾 2 字节

Q&A