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 基本一致,但具体覆盖范围由协议规范定义,实现时需严格按包结构确定起始和结束位置。

CCSDS 与 SpaceWire 虽然都使用 CRC-16/CCITT,但校验覆盖范围不同:CCSDS 通常从帧头之后开始,SpaceWire 则从逻辑地址开始。实现时不能只复用算法函数,还要确认数据指针和长度。

三、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 位宽度和反射机制,提供更强的检错能力,适合长数据块。

六、实现要点与常见陷阱

在实际星载软件开发中,建议遵循以下做法:

  1. 先确认协议规范中的参数表,不要凭经验假设初值或反射设置。
  2. 统一位序约定:CCSDS 和 SpaceWire 用 MSB-first,CAN 用 LSB-first,代码中应显式标注。
  3. 用标准测试向量验证:例如对 ASCII 字符串 “123456789” 计算 CRC,CRC-16/CCITT-FALSE 的结果应为 0x29B1,CRC-32/ISO-HDLC 的结果应为 0xCBF43926,CRC-16/ARC 的结果应为 0xBB3D。
  4. 区分硬件 CRC 与软件 CRC:FPGA 或 MCU 硬件 CRC 外设可能固定了反射和初值,使用前需核对是否与协议一致。
  5. 注意数据覆盖范围:同一算法在不同协议中覆盖的字段不同,起始指针和长度必须按规范确定。
若收发两端使用了不同的 CRC 参数,即使数据完全正确,校验也会持续失败。排查时应先比对参数表,再用标准测试向量确认实现是否正确,最后检查数据覆盖范围。
星载常用 CRC 标准参数与总线映射 多项式 · 初值 · 反射 · 异或 · 位序 · 应用场景 CRC-16/CCITT 多项式:0x1021 初值:0xFFFF 输入反射:否 输出反射:否 结果异或:0x0000 位序:MSB-first 应用:CCSDS / SpaceWire CRC-32/ISO-HDLC 多项式:0x04C11DB7 初值:0xFFFFFFFF 输入反射:是 输出反射:是 结果异或:0xFFFFFFFF 位序:LSB-first 应用:载荷数据 / 存储块 CRC-16/ARC 多项式:0x8005 初值:0x0000 输入反射:是 输出反射:是 结果异或:0x0000 位序:LSB-first 应用:CAN 总线 / Modbus 总线 / 协议映射关系 CCSDS 传输帧 CRC-16/CCITT · MSB-first SpaceWire 数据包 CRC-16/CCITT · MSB-first CAN 2.0B 帧 CRC-16/ARC · LSB-first 载荷数据块 / 固态存储 · CRC-32/ISO-HDLC 标准测试向量 “123456789” CCITT:0x29B1 · HDLC:0xCBF43926 · ARC:0xBB3D

总结来看,星载 CRC 选型应遵循“协议优先、参数对齐、位序一致、测试验证”的原则。CRC-16/CCITT 服务于 CCSDS 与 SpaceWire 的帧校验,CRC-32/ISO-HDLC 承担大容量数据与存储保护,CRC-16/ARC 则适配 CAN 总线的短帧通信。掌握这三类标准的参数差异,是星载数据完整性设计的基础能力。