3. 星载常用CRC标准与参数解析
在星载数据链路中,CRC 并不是一个“随便选一个多项式就能用”的通用算法。同一段数据,换一个初值、换一种位序处理方式,得到的校验结果可能完全不同。因此,理解 CRC 标准的关键,不是记住某个多项式,而是掌握一组决定其行为的参数模型:多项式、初值、输入反射、输出反射、结果异或值,以及数据位序约定。只有这些参数完全一致,收发两端才能正确校验。
本节围绕星载与航天总线中最常见的三类 CRC 标准展开:CRC-16/CCITT、CRC-32/ISO-HDLC 和 CRC-16/ARC,并说明它们在 CCSDS、SpaceWire、CAN 总线中的典型配置与差异。
一、CRC 参数模型:五个必须对齐的要素
一个 CRC 算法通常由以下参数唯一确定:
- 多项式(Polynomial):决定生成多项式的位宽和反馈抽头,例如 CRC-16/CCITT 常用 0x1021。
- 初值(Init):寄存器在计算开始前的初始状态,常见为 0x0000、0xFFFF 或 0xFFFFFFFF。
- 输入反射(RefIn):每个输入字节是否按位反转后再进入运算。
- 输出反射(RefOut):最终结果是否按位反转后输出。
- 结果异或(XorOut):输出前与固定值异或,常见为 0x0000 或 0xFFFF。
此外,数据位序(MSB-first 或 LSB-first)也会影响实际计算结果。星载协议中,CCSDS 和 SpaceWire 通常采用 MSB-first,而 CAN 总线在 CRC 计算时采用 LSB-first 的位序约定。若实现时忽略这一点,即使参数表看起来一致,校验也会失败。
二、CRC-16/CCITT:CCSDS 与 SpaceWire 的主力
CRC-16/CCITT 是航天领域最经典的 16 位 CRC 之一。其标准参数为:多项式 0x1021,初值 0xFFFF,输入不反射,输出不反射,结果异或 0x0000。该配置常被称为 “CRC-16/CCITT-FALSE”,因为初值取 0xFFFF 而非 0x0000。
在 CCSDS 遥测与遥控链路中,CRC-16/CCITT 被广泛用于帧校验。CCSDS 的传输帧通常采用 MSB-first 位序,CRC 计算覆盖帧头之后的有效数据区。发送端将计算得到的 16 位校验码附加在帧尾,接收端对相同区域重新计算并比对。若结果不一致,该帧被标记为错误并丢弃或请求重传。
在 SpaceWire 链路中,CRC-16/CCITT 同样用于数据包校验。SpaceWire 的 CRC 计算覆盖数据包中的逻辑地址、协议标识、数据长度和数据字段,采用 MSB-first 逐位处理。其参数与 CCSDS 基本一致,但具体覆盖范围由协议规范定义,实现时需严格按包结构确定起始和结束位置。
三、CRC-32/ISO-HDLC:高完整性数据与存储保护
CRC-32/ISO-HDLC 是 32 位 CRC 中最常见的标准,广泛用于以太网、ZIP、PNG 以及星载大容量数据存储。其参数为:多项式 0x04C11DB7,初值 0xFFFFFFFF,输入反射,输出反射,结果异或 0xFFFFFFFF。
在星载数据系统中,CRC-32/ISO-HDLC 常用于有效载荷数据文件、固态存储器块和高速数据链路的完整性保护。由于 32 位 CRC 的漏检概率远低于 16 位,它适合对长数据块进行校验。例如,一颗遥感卫星的载荷数据被分割为若干数据块,每块附加 4 字节 CRC-32,地面接收后逐块校验,只有全部通过才进行后续处理。
需要注意的是,CRC-32/ISO-HDLC 的输入反射和输出反射均为真,这意味着实现时通常采用 LSB-first 的查表方式。若在 FPGA 中直接按 MSB-first 实现,必须显式进行位反转,否则结果与标准不符。
四、CRC-16/ARC:CAN 总线的经典选择
CRC-16/ARC 是另一种 16 位 CRC,参数为:多项式 0x8005,初值 0x0000,输入反射,输出反射,结果异或 0x0000。它常见于 CAN 总线、Modbus 等工业与车载总线。
在 CAN 总线中,CRC 用于帧校验。CAN 2.0B 的 CRC 计算覆盖帧起始、仲裁场、控制场和数据场,采用 LSB-first 位序。其多项式为 0x8005,初值为 0x0000,输入和输出均反射。CAN FD 在数据段使用更长的 CRC 多项式,但经典 CAN 仍以 CRC-16/ARC 为基础。
星载系统中,CAN 总线常用于平台低速遥测遥控、载荷辅助控制和星内设备互联。由于 CAN 帧较短,CRC-16/ARC 足以提供可靠的检错能力。实现时需注意:CAN 控制器的硬件 CRC 通常自动完成计算,软件模拟时则必须严格遵循 LSB-first 和反射约定。
五、三类标准的关键差异对比
下表汇总了三类标准的核心参数,便于实现时快速对照:
| 标准 | 多项式 | 初值 | 输入反射 | 输出反射 | 结果异或 | 典型应用 |
|---|---|---|---|---|---|---|
| CRC-16/CCITT | 0x1021 | 0xFFFF | 否 | 否 | 0x0000 | CCSDS、SpaceWire |
| CRC-32/ISO-HDLC | 0x04C11DB7 | 0xFFFFFFFF | 是 | 是 | 0xFFFFFFFF | 载荷数据、存储块 |
| CRC-16/ARC | 0x8005 | 0x0000 | 是 | 是 | 0x0000 | CAN 总线、Modbus |
从表中可以看出,CRC-16/CCITT 与 CRC-16/ARC 虽然都是 16 位,但多项式、初值和反射设置完全不同,结果不可互换。CRC-32/ISO-HDLC 则通过 32 位宽度和反射机制,提供更强的检错能力,适合长数据块。
六、实现要点与常见陷阱
在实际星载软件开发中,建议遵循以下做法:
- 先确认协议规范中的参数表,不要凭经验假设初值或反射设置。
- 统一位序约定:CCSDS 和 SpaceWire 用 MSB-first,CAN 用 LSB-first,代码中应显式标注。
- 用标准测试向量验证:例如对 ASCII 字符串 “123456789” 计算 CRC,CRC-16/CCITT-FALSE 的结果应为 0x29B1,CRC-32/ISO-HDLC 的结果应为 0xCBF43926,CRC-16/ARC 的结果应为 0xBB3D。
- 区分硬件 CRC 与软件 CRC:FPGA 或 MCU 硬件 CRC 外设可能固定了反射和初值,使用前需核对是否与协议一致。
- 注意数据覆盖范围:同一算法在不同协议中覆盖的字段不同,起始指针和长度必须按规范确定。
总结来看,星载 CRC 选型应遵循“协议优先、参数对齐、位序一致、测试验证”的原则。CRC-16/CCITT 服务于 CCSDS 与 SpaceWire 的帧校验,CRC-32/ISO-HDLC 承担大容量数据与存储保护,CRC-16/ARC 则适配 CAN 总线的短帧通信。掌握这三类标准的参数差异,是星载数据完整性设计的基础能力。