4、RTCM 3.x消息帧结构:同步码、保留位、消息长度、CRC校验,帧解析流程

RTCM 3.x(Radio Technical Commission for Maritime Services,国际海运事业无线电技术委员会)协议是GNSS差分改正数传输的事实标准,广泛应用于RTK(实时动态载波相位差分)测量、PPP-RTK、网络RTK(如VRS、FKP、MAC)以及精密农业、自动驾驶、无人机定位等场景。与RTCM 2.x的变长、无强校验、面向字符的帧格式不同,RTCM 3.x采用固定8位同步码、12位消息长度、24位CRC-24Q校验的二进制帧结构,具有极高的抗误码能力和解析效率。本章将深入拆解RTCM 3.x帧的每一个比特位,给出严谨的帧解析流程,并结合实际抓包数据演示从字节流到消息内容的完整解码过程。

RTCM 3.x 帧结构总览与解析流程 同步码 8 bit 0xD3 保留 6 bit 全0 消息 10 bit 长度 … 消息数据(可变长度,由消息长度字段决定) 消息头(12 bit) + 消息体(可变) + 填充位(对齐到字节) 例如:1005站坐标、1077全星座观测值、1230天线描述 … CRC-24Q 24 bit 多项式0x1864CFB 固定值 校验范围 帧解析流程(状态机) ① 搜索同步码 逐字节匹配0xD3 ② 读取长度 2字节:保留+长度 ③ 接收数据 长度+3字节CRC ④ CRC校验 CRC-24Q计算 通过 → 解析消息体 按消息类型解码 失败 → 丢弃并重同步 从下一字节重新搜索 固定字段 长度字段 消息数据 CRC校验

上图展示了RTCM 3.x帧的完整结构以及从字节流中提取一帧数据的核心状态机流程。下面我们将从帧结构各字段的位级定义开始,逐步深入到CRC校验算法和实际解析代码实现。

4.1 帧结构各字段位级定义

核心原理:RTCM 3.x帧采用大端(Big-Endian)字节序,所有多字节字段均按高位在前的方式传输。帧总长度 = 1字节同步码 + 2字节长度字段 + N字节消息数据 + 3字节CRC,其中N由长度字段的10个比特决定,取值范围为0~1023字节。整个帧的最小长度为6字节(N=0时),最大长度为1029字节。

字段名称比特数字节偏移取值/含义备注
同步码(Preamble)80固定0xD3(二进制1101 0011)用于帧边界识别,不可与其他字段混淆
保留位(Reserved)61(高6位)固定为0协议预留,未来扩展使用,当前必须为0
消息长度(Message Length)101(低2位)+2(全部8位)0~1023,表示消息数据(不含同步码、长度字段和CRC)的字节数长度字段共16位,但高6位为保留位,实际有效长度仅10位
消息数据(Message Data)可变3 ~ 3+N-1包含消息头(12位消息类型)+ 消息体 + 填充位填充位用于将消息体对齐到字节边界,填充位值无意义
CRC校验(CRC-24Q)243+N ~ 3+N+2对同步码之后的所有字节(即长度字段+消息数据)进行CRC-24Q计算多项式0x1864CFB,初始值0x000000

判断方法:解析时,首先读取第一个字节,若等于0xD3则初步认为找到同步码。但仅凭一个字节不能完全确认帧边界,因为消息数据中也可能出现0xD3。因此必须结合长度字段和CRC校验来最终确认。读取第2、3字节后,提取低10位作为消息长度N,然后连续读取N+3字节(消息数据+CRC),对长度字段和消息数据计算CRC-24Q,与接收到的CRC比对。若一致,则确认这是一个完整且正确的RTCM 3.x帧。

实战经验:在串口或网络流中,0xD3可能出现在任何位置。高效的解析器应使用状态机而非逐字节搜索。当处于“搜索同步码”状态时,每收到一个字节就与0xD3比较;一旦匹配,立即切换到“读取长度”状态,并启动超时计时器。若在超时时间内未收到足够字节,则回到搜索状态,避免因数据流中断导致解析卡死。

4.2 CRC-24Q校验算法详解

核心原理:CRC-24Q是RTCM 3.x专用的循环冗余校验算法,其生成多项式为0x1864CFB(二进制:1 1000 0110 0100 1100 1111 1011),初始值为0x000000,输入数据按位处理,不进行反射(即MSB-first),输出结果直接附加在消息末尾。该算法能检测出所有长度≤24比特的突发错误,以及绝大多数更长的错误模式,非常适合无线和串行链路。

操作流程:CRC计算的输入范围是从长度字段的第一个字节开始,一直到消息数据的最后一个字节,不包含同步码和CRC本身。具体步骤如下:

  1. 初始化CRC寄存器为0x000000。
  2. 对输入字节流中的每一位(从最高位MSB开始),执行以下操作:
    a. 将CRC寄存器左移1位,最低位补0;
    b. 若移出的最高位(原CRC第23位)与当前输入位异或结果为1,则CRC寄存器与多项式0x1864CFB进行异或。
  3. 处理完所有字节后,CRC寄存器中的24位值即为校验码。
// C语言实现CRC-24Q(RTCM 3.x)
uint32_t crc24q(const uint8_t *data, size_t len) {
    uint32_t crc = 0;
    for (size_t i = 0; i < len; i++) {
        crc ^= ((uint32_t)data[i]) << 16;  // 将字节放入CRC最高字节
        for (int j = 0; j < 8; j++) {
            crc <<= 1;
            if (crc & 0x1000000) {  // 检查第24位
                crc ^= 0x1864CFB;   // 异或多项式
            }
        }
    }
    return crc & 0xFFFFFF;  // 取低24位
}

案例拆解:假设收到一帧RTCM 3.x数据,十六进制为:D3 00 06 10 05 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00