4. DroneCAN报文结构
DroneCAN 建立在经典 CAN 2.0B 之上,使用 29 位扩展帧标识符承载协议语义。理解报文结构,是后续抓包分析、故障定位和节点调试的基础。本节从帧类型、优先级、CAN ID 分配、多帧传输以及动态节点 ID 与即插即用机制五个方面展开,帮助你在 Wireshark 或 candump 中快速读懂每一帧的含义。
一、帧类型与 CAN ID 的位域划分
DroneCAN 的 29 位 CAN ID 并非随机分配,而是被划分为若干语义字段。标准格式如下:
29 位 CAN ID 位域(从高位到低位):
[28:25] 传输优先级 Priority (0 最高,31 最低)
[24:16] 数据类型 Data Type ID (消息/服务类型编号)
[15:8] 源节点 ID Source Node ID
[7:0] 目标节点/保留字段
- 广播消息:低 8 位为 0
- 单播/服务:低 8 位为目标节点 ID
- 匿名消息:使用特殊保留值
由此可以看出,DroneCAN 报文天然分为三类:广播消息(如 uavcan.protocol.NodeStatus)、单播消息(点对点传输)和服务请求/响应(Service)。此外还有一类特殊的匿名消息,用于节点在尚未获得 ID 时进行动态分配协商。
二、传输优先级
优先级字段位于 CAN ID 的最高位,数值越小优先级越高。CAN 总线仲裁时,ID 越小越先发送,因此 DroneCAN 通过优先级字段实现了确定性的实时调度。常见约定如下:
| 优先级值 | 典型用途 | 说明 |
|---|---|---|
| 0~3 | 紧急安全消息 | 如故障告警、急停指令 |
| 4~7 | 实时控制 | 执行器指令、姿态控制 |
| 8~15 | 状态与遥测 | NodeStatus、传感器数据 |
| 16~23 | 配置与参数 | 参数读写、节点配置 |
| 24~31 | 调试与日志 | 非实时诊断信息 |
三、多帧传输机制
CAN 单帧数据场最多 8 字节,而 DroneCAN 的许多消息(如固件升级、日志、大数组)远超此限制。为此 DroneCAN 定义了多帧传输协议,将长消息拆分为首帧、中间帧和尾帧,通过 CRC 校验保证完整性。
多帧传输结构:
首帧 Start Frame
- 传输 ID、总长度、CRC 种子
中间帧 Middle Frame
- 序号递增,携带数据片段
尾帧 End Frame
- 最后数据 + CRC 校验值
接收方按传输 ID 重组,校验失败则丢弃整条消息
多帧传输的关键在于传输 ID,它使得同一总线上多个节点的多帧消息可以交错传输而不混淆。抓包分析时,应关注首帧中的总长度与后续帧序号是否连续,若出现序号跳跃或 CRC 错误,通常意味着总线干扰或节点发送异常。
四、动态节点 ID 与即插即用机制
DroneCAN 最实用的特性之一是动态节点 ID 分配。节点上电后若未配置固定 ID,会先发送匿名消息参与 ID 分配协商,通过唯一标识(如硬件 UUID)竞争一个空闲 ID。这一过程无需人工干预,实现了即插即用。
分配流程大致如下:
- 节点上电,检测自身是否已有固定 ID;
- 若无,则发送匿名 NodeStatus 广播,声明自身存在;
- 总线上的分配器(通常是飞控)根据 UUID 和当前占用情况,分配一个空闲 ID;
- 节点收到分配结果后,切换到该 ID 并开始正常通信;
- 若发生冲突,节点重新进入匿名状态并再次协商。
五、综合案例与抓包判读
假设你在抓包中看到如下 CAN ID:0x0C7A0123。按位域拆解:
0x0C7A0123 = 二进制 0 1100 0111 1010 0000 0001 0010 0011
优先级 = 0b00110 = 6
数据类型 = 0b001111010 = 0x7A
源节点 = 0x01
目标/保留 = 0x23
由此可判断:这是一条优先级为 6 的实时控制类消息,源节点 ID 为 1,低 8 位非零,说明是单播或服务响应。结合数据类型编号查表,即可确定具体消息名称。
常见误区包括:把 CAN ID 当作纯编号记忆而忽略位域含义;在多帧传输中只看单帧数据而忽略重组;以及认为动态 ID 分配一定成功。复盘时应养成“先拆位域、再看类型、后查多帧”的判读习惯。