3. DroneCAN协议栈概览

DroneCAN 源自 UAVCAN,是面向无人机与嵌入式控制网络的高可靠总线协议。它运行在 CAN/CAN FD 物理层之上,通过标准化的节点寻址、传输层分帧、应用层服务与 DSDL 数据类型,把飞控、电调、GPS、电源模块、空速计等设备组织成一个可自描述、可在线配置的实时网络。理解协议栈的分层关系,是后续抓包、诊断和排障的基础。

一、从 UAVCAN v0 到 DroneCAN 的演进

UAVCAN v0 是最早在开源无人机生态中广泛部署的版本,采用 29 位扩展帧、固定 1 Mbps 经典 CAN、基于节点 ID 的匿名/动态分配机制,以及以 DSDL 描述的数据类型。它的传输层支持单帧、多帧和广播,应用层提供参数、固件升级、节点状态等服务。由于 v0 在 CAN FD、时间同步、安全性和大载荷传输上存在局限,社区随后推进 UAVCAN v1,引入更严格的类型系统、即插即用注册、CAN FD 支持和更清晰的命名空间。

DroneCAN 可以理解为 UAVCAN v0 的工程化延续与生态固化版本:它保留了 v0 的帧格式、DSDL 定义和大量现成设备兼容性,同时由 DroneCAN 组织维护规范、工具链和参考实现。对诊断而言,关键差异在于:v0/DroneCAN 使用 29 位 ID 中的源节点 ID、目标节点 ID、消息类型 ID 和优先级字段;而 v1 的 ID 分配和传输语义有较大变化。抓包时若看到 29 位 ID 中源地址、目标地址和类型 ID 的固定位段,通常就是 DroneCAN 流量。

抓包识别要点:DroneCAN 经典帧的 29 位 ID 可拆为优先级、消息类型 ID、源节点 ID、目标节点 ID(服务请求/响应时)等字段。先解析 ID,再解析数据段,是诊断的第一步。

二、节点 ID 分配与网络角色

每个 DroneCAN 节点在总线上必须拥有唯一的节点 ID,范围通常为 1~127,0 保留给匿名节点,255 常用于广播或无效地址。节点 ID 的获取方式主要有三种:静态配置、动态分配和匿名启动。静态配置适合飞控、电调等固定角色;动态分配由分配器节点通过 uavcan.protocol.dynamic_node_id.Allocation 服务完成,新节点先以匿名身份发送请求,分配器根据唯一 ID 分配可用地址;匿名启动则用于尚未获得 ID 的节点,只能发送有限类型的消息。

节点 ID 冲突是现场最常见的故障之一。两个设备配置了相同 ID 时,总线会出现随机丢包、参数读写失败、固件升级中断等现象。诊断时应先通过抓包统计各源地址的出现频率,再结合设备清单核对 ID 分配表。

角色典型节点 ID说明
飞控1~10常作为分配器与参数服务器
电调20~50多路电调按顺序分配
GPS/罗盘60~80可能同时提供多个消息类型
电源模块90~100发布电池状态与电流电压
匿名节点0未分配 ID,仅限特定消息

三、传输层:分帧、重组与可靠性

DroneCAN 传输层负责把应用层消息拆分为 CAN 帧,并在接收端重组。对于不超过 7 字节(经典 CAN)或 63 字节(CAN FD)的载荷,可使用单帧传输;更大的载荷则使用多帧传输。多帧传输通过传输 ID、帧索引和末帧标志来标识同一消息的分片,接收端按序重组,超时或丢片则丢弃整条消息。

传输层还定义了广播与单播两种语义。广播消息没有目标节点 ID,所有节点都可接收;单播服务请求和响应则携带目标节点 ID,只有目标节点处理并回复。抓包分析时,若发现大量重传、帧索引跳跃或重组超时,通常意味着总线负载过高、终端电阻异常或某节点发送异常。

# 典型 DroneCAN 多帧传输观察(伪日志)
CAN ID: 0x1C0A1234  DLC: 8  DATA: 01 02 03 04 05 06 07 08
CAN ID: 0x1C0A1234  DLC: 8  DATA: 09 0A 0B 0C 0D 0E 0F 10
CAN ID: 0x1C0A1234  DLC: 4  DATA: 11 12 13 14
# 同一传输 ID 连续出现,末帧标志置位后完成重组

四、应用层、DSDL 数据类型与参数服务

应用层建立在传输层之上,定义了节点状态、参数、固件升级、时间同步、动态节点 ID 分配等服务。DSDL(DroneCAN Data Structure Language)是描述消息和服务的数据结构语言,每个消息类型有唯一的类型 ID 和固定字段布局。常见类型包括 uavcan.protocol.NodeStatus、uavcan.equipment.power.BatteryInfo、uavcan.equipment.esc.RawCommand 等。DSDL 文件编译后生成各语言的绑定代码,保证不同厂商设备对同一消息的解析一致。

参数服务是 DroneCAN 诊断中使用频率最高的应用层功能。它允许地面站读取和写入节点参数,参数以名称、类型和值的形式组织,支持整数、实数、布尔和字符串。参数读写通过 uavcan.protocol.param.GetSet 服务完成,请求中携带参数名或索引,响应返回参数值和结果码。参数服务也是固件升级、传感器校准和故障恢复的入口。

诊断技巧:当参数读取失败时,先确认目标节点是否在线、节点 ID 是否正确、总线是否出现错误帧;再检查参数名是否存在于该节点的 DSDL 定义中。很多“参数不存在”其实是节点固件版本与地面站 DSDL 版本不匹配。

五、协议栈分层关系图

下图把 DroneCAN 协议栈从物理层到应用层、DSDL 与参数服务的纵向关系,以及节点 ID 分配、传输层分帧、应用层服务之间的横向联系集中呈现,便于在抓包时快速定位问题所在层。

DroneCAN 协议栈分层与关键机制 应用层 Application Layer 节点状态 参数服务 固件升级 时间同步 动态ID分配 DSDL 数据类型定义 消息类型 ID · 字段布局 · 服务定义 · 编译生成绑定代码 uavcan.protocol.param.GetSet uavcan.equipment.power.BatteryInfo 传输层 Transport Layer 单帧传输 ≤7B / ≤63B 多帧分片重组 传输ID · 帧索引 · 末帧 广播 / 单播 目标节点 ID 寻址 超时与重传 丢片丢弃整条消息 物理层 / 数据链路层 CAN 2.0B 扩展帧 · 29 位 ID · 1 Mbps · CAN FD 可选 · 120Ω 终端电阻 节点 ID 分配流程 上电匿名启动 发送分配请求 分配器分配 ID 节点确认并启用 在线

六、常见误区与复盘

  • 把 DroneCAN 等同于 CAN:CAN 只提供物理层和帧格式,DroneCAN 在其上定义了寻址、传输、应用和数据类型,诊断时必须分层看。
  • 忽略节点 ID 冲突:ID 冲突不会总是报错,更多表现为间歇性丢包和参数读写失败,需通过抓包统计源地址发现。
  • DSDL 版本不匹配:地面站与节点固件的 DSDL 定义不一致时,参数名和消息字段会解析错误,表现为“参数不存在”或数值异常。
  • 多帧重组超时误判为节点故障:总线负载高、终端电阻缺失或线缆过长都会导致分片丢失,应先检查物理层再怀疑节点。

排障顺序建议:物理层(终端电阻、线序、供电)→ 数据链路层(错误帧、总线负载)→ 传输层(分片、重传、超时)→ 应用层(节点状态、参数服务)→ DSDL 版本一致性。按层排查可避免在错误层级反复试错。

掌握协议栈分层、节点 ID 分配、传输层分帧、应用层服务与 DSDL 参数服务之后,后续抓包分析就能把每一帧数据准确映射到具体层级和具体节点,从而快速定位丢包、冲突、参数异常和固件升级失败等问题。