2. DroneCAN协议基础
DroneCAN 是建立在经典 CAN 总线之上的轻量级应用层协议,理解它必须从物理层、帧结构、节点寻址和消息机制四个层面逐级展开。对于固件升级工程而言,这些基础直接决定了升级指令能否可靠下发、目标节点能否被正确识别、大数据块能否被稳定传输。
一、CAN总线原理:差分信号与仲裁机制
CAN 总线采用差分信号传输,两条信号线 CAN_H 与 CAN_L 的电压差表示逻辑电平。当差分电压约为 0V 时表示显性位(逻辑 0),约为 2V 时表示隐性位(逻辑 1)。这种差分结构使总线在电机、电调等强电磁干扰环境中仍能保持较高可靠性,这也是无人机内部总线选择 CAN 的核心原因。
CAN 总线两端必须各接一个 120Ω 终端电阻,用于吸收信号反射。若终端电阻缺失或只接一端,波形会出现振铃,表现为随机错误帧、节点掉线,在固件升级过程中则可能造成数据块校验失败。总线仲裁基于“显性覆盖隐性”的规则:多个节点同时发送时,ID 数值越小优先级越高,发送显性位的节点继续占用总线,发送隐性位的节点自动退让并转为接收。这一机制保证了高优先级消息(如紧急状态、关键控制指令)的实时性。
二、DroneCAN帧格式:从CAN帧到应用层消息
DroneCAN 使用扩展帧(29 位标识符),将 CAN ID 划分为多个字段,承载源节点、目标节点、消息类型和服务类型等信息。标准数据帧最多携带 8 字节数据,DroneCAN 通过多帧传输机制支持超过 8 字节的消息。
对于单帧消息,数据段直接存放序列化的消息内容;对于多帧消息,首帧携带总长度和传输类型,后续帧按序携带数据片段,接收方重组后交给对应消息类型的解码器。固件升级中的大块数据正是依赖这一机制分片传输。
DroneCAN 扩展帧 ID 字段示意(概念划分):
[ 优先级 ][ 消息类型 ][ 服务类型 ][ 源节点ID ][ 目标节点ID ]
高优先级 标识消息 请求/响应 发送方 接收方
单帧:数据段 = 序列化消息体(≤ 8 字节)
多帧:首帧 = 总长度 + 传输类型;后续帧 = 数据片段
三、节点ID分配:唯一寻址与动态分配
每个 DroneCAN 节点必须拥有唯一的节点 ID(通常 1~127),它是消息路由和固件升级寻址的基础。节点 ID 冲突会导致总线通信异常,表现为消息丢失、节点响应错乱,升级时可能把固件写入错误节点。
节点 ID 可通过静态配置或动态分配获得。动态分配依赖 DNA(Dynamic Node Allocation)服务:新节点上电后广播请求,分配器返回可用 ID,节点确认后使用该 ID 参与通信。工程中建议对关键节点(飞控、电调、GPS)采用静态 ID,避免上电顺序变化导致 ID 漂移,从而影响升级脚本的稳定性。
- 静态分配:配置文件或参数中固定节点 ID,适合飞控、关键传感器。
- 动态分配:通过 DNA 服务协商,适合即插即用设备。
- 冲突检测:节点应监听总线,发现 ID 被占用时重新申请。
四、消息类型与通信机制
DroneCAN 消息分为广播消息、请求/响应服务、以及带确认的传输服务。广播消息用于周期性状态发布,如节点状态、电池信息;服务请求用于参数读写、固件升级指令;传输服务用于可靠的大数据块传输。
通信机制上,DroneCAN 支持超时重传、序列号校验和确认应答。固件升级通常使用 file 相关服务:先请求开始升级,再分块写入,最后校验并重启。若某一块未收到确认,发送方会重传,直到超时或达到重试上限。
| 消息/服务类型 | 典型用途 | 通信方式 | 升级场景中的作用 |
|---|---|---|---|
| NodeStatus | 节点健康状态 | 周期广播 | 确认目标节点在线 |
| GetNodeInfo | 获取节点信息 | 请求/响应 | 识别硬件与固件版本 |
| param 读写 | 参数配置 | 请求/响应 | 升级前备份、升级后恢复 |
| file 服务 | 文件读写 | 多帧传输 | 固件数据分块下发 |
| Restart | 节点重启 | 请求/响应 | 升级完成后生效 |
五、案例与误区复盘
某次电调固件升级失败,日志显示目标节点间歇性无响应。排查发现总线上两个电调被配置为相同节点 ID,导致响应冲突。改为唯一 ID 后升级成功。另一个常见误区是忽略终端电阻:总线末端未接 120Ω,短距离测试正常,但装机后线缆变长,升级大块数据时频繁校验失败。
掌握以上四层基础后,后续固件升级流程中的每一步都能对应到具体协议行为:节点 ID 决定“发给谁”,帧格式决定“怎么装”,消息类型决定“用什么服务”,通信机制决定“如何保证可靠”。在工程实践中,建议先用 dronecan_gui_tool 或 uavcan_gui_tool 扫描总线,确认节点列表与 ID,再执行升级脚本,可显著降低失败率。