CAN、DroneCAN与Cyphal边界¶
控制器局域网(CAN,Controller Area Network)提供多节点总线、逐位仲裁、帧错误检测和错误隔离。DroneCAN和Cyphal在CAN之上定义不同的传输与数据类型体系;共用CAN收发器不代表协议兼容。

先区分三层¶
| 层 | 内容 |
|---|---|
| 物理层 | CAN_H、CAN_L、收发器、终端、电缆和拓扑 |
| CAN数据链路层 | 标识符、仲裁、数据字段、链路CRC、确认和错误帧 |
| 上层协议 | DroneCAN/UAVCAN v0、Cyphal/UAVCAN v1或厂商协议 |
看到合法CAN帧只能证明前两层部分工作。只有按正确上层规范解释标识符、尾字节、传输CRC和数据类型,才能得到消息。
物理总线¶
典型高速CAN使用差分双线和总线两端终端。工程记录至少包括:
- 收发器标准和电压;
- 标称仲裁速率;
- CAN FD时的数据阶段速率;
- 线束长度、支线长度和拓扑;
- 两端终端及断电等效电阻;
- 节点供电和公共参考策略;
- 共模范围;
- 隔离;
- 连接器和屏蔽。
“总线两端各120欧姆”是常见拓扑原则,不等于任意断电测量都必须正好60欧姆。节点内部偏置、保护器件、隔离和其他并联路径会影响读数,应以系统设计和测量条件解释。
CAN仲裁¶
多个节点同时发送时,从标识符高位开始逐位仲裁:
- 显性位覆盖隐性位;
- 发送隐性却读到显性的节点停止本次发送;
- 数值更小的标识符通常赢得仲裁;
- 失败节点不是发生传输错误,可在总线空闲后重试。
因此,把协议优先级放在29位扩展标识符高位,可以直接影响仲裁。持续高优先级流量也可能让低优先级传输长期延迟。
CAN已有的保护¶
每个CAN数据帧已有链路层CRC、位填充检查、格式检查、确认和错误处理。它们用于发现总线传输错误,不提供:
- 节点身份认证;
- 载荷保密;
- 高层传输完整性;
- 防重放;
- 命令授权。
多帧上层协议仍可能需要覆盖完整传输的CRC。
DroneCAN命名边界¶
DroneCAN延续原UAVCAN v0协议。资料中还可能把DroneCAN自身的演进版本称为“DroneCAN v1”,这不能与UAVCAN v1/Cyphal混为一谈。
本文使用:
DroneCAN/UAVCAN v0:经典的v0线协议;Cyphal/UAVCAN v1:后继Cyphal协议;DroneCAN CAN FD扩展:DroneCAN项目后续定义的FD承载。
DroneCAN的29位标识符¶
DroneCAN经典CAN只使用CAN 2.0B的29位扩展标识符。
广播消息¶
普通消息标识符包含:
- 5位优先级;
- 16位消息数据类型ID;
- 消息/服务区分位为消息;
- 7位源节点ID。
消息传输广播给总线上其他节点。
服务¶
服务标识符包含:
- 5位优先级;
- 8位服务数据类型ID;
- 请求/响应位;
- 7位目标节点ID;
- 消息/服务区分位为服务;
- 7位源节点ID。
服务由点对点请求和响应组成,不应因CAN物理广播特性而描述为“服务广播”。响应必须与请求的数据类型、节点关系和传输ID对应。
优先级和节点¶
- 优先级范围为0至31;
- 数值0优先级最高;
- 普通已分配节点ID范围为1至127;
- 节点ID 0用于匿名传输的特殊语义;
- 同一多帧传输的CAN ID和优先级保持一致。
节点ID用于寻址,不是安全身份。
Tail byte¶
每个DroneCAN CAN帧的数据字段最后一个字节是Tail byte:
| 位 | 含义 |
|---|---|
| 7 | Start of transfer |
| 6 | End of transfer |
| 5 | Toggle |
| 4至0 | Transfer-ID,模32 |
单帧传输:
- Start为1;
- End为1;
- Toggle为0;
- 经典CAN下一帧最多有7字节上层载荷。
多帧传输:
- 首帧Start为1;
- 末帧End为1;
- 首帧Toggle为0,后续逐帧翻转;
- 每帧Transfer-ID一致;
- 接收端按来源、类型、方向和Transfer-ID维护重组状态。
多帧传输CRC¶
只有多帧DroneCAN传输增加16位传输CRC:
- 算法为CRC-16/CCITT-FALSE;
- 初值
0xFFFF; - 多项式
0x1021; - 不反射;
- 输出异或为0;
- 输入为数据类型签名的64位小端表示,再接完整序列化载荷;
- 计算结果按低字节、再高字节的顺序位于传输数据流最前面。
这个传输CRC与每个CAN帧由控制器处理的链路CRC不同。单帧传输没有额外传输CRC。
数据类型与序列化¶
DroneCAN数据类型定义包含:
- 全名;
- 数据类型ID;
- 64位数据类型签名;
- 字段类型和数组边界;
- 服务请求与响应定义;
- 版本与命名空间。
实现通常由数据结构描述语言(DSDL,Data Structure Description Language)定义生成序列化代码。手工按C结构体复制会遇到位字段、尾数组优化、端序和填充问题。
发送端与接收端必须使用匹配的数据类型定义。ID相同但签名或字段定义不同,会使传输CRC或语义不一致。
Transfer-ID与时间边界¶
Transfer-ID按传输描述符分别维护。描述符至少区分传输种类、数据类型、源节点,以及服务场景中的目标和请求/响应方向。不能为整条CAN总线只维护一个Transfer-ID。
5位Transfer-ID按模32递增,但接收端不能脱离时间解释:
- 连续传输用预期的下一Transfer-ID检测重复和丢失;
- 发送端可删除至少2秒未使用的Transfer-ID映射;以后重新创建该映射时,Transfer-ID必须从0初始化,不是从任意值开始;
- 接收端的Transfer-ID超时为2秒;超时后可把下一合法起始帧作为新序列接受,因此它可能看到与旧序列不连续的Transfer-ID;
- 消息或服务传输若无法在1秒内完成应中止;服务客户端等待响应的推荐上限也是1秒,应用若改变必须明确记录;
- 节点重启、动态节点ID变化和接收状态过期都要清理相应重组状态;
- 在超时窗口外重新出现的帧不能简单按“旧序号重放”永久拒绝。
测试应覆盖模32回绕、2秒内重复、超过2秒重新开始、多帧中断、节点重启和服务响应超时。
匿名传输¶
未分配节点可使用受限的匿名消息发现分配服务。匿名传输:
- 源节点ID为0;
- CAN ID中的消息类型ID空间受限;
- 加入判别值;
- 只能使用单帧;
- 不能直接承担普通服务通信。
匿名节点不是“节点ID冲突时继续正常工作”的通用模式。
Cyphal不是线兼容升级¶
Cyphal是UAVCAN v1的现名。它可使用相同CAN_H/CAN_L布线和29位扩展帧,但与DroneCAN/UAVCAN v0的CAN传输不兼容。
| 项目 | DroneCAN/UAVCAN v0 | Cyphal/CAN v1 |
|---|---|---|
| 优先级 | 5位,32级 | 3位,8级 |
| 消息标识 | 16位数据类型ID | 13位Subject-ID |
| 服务标识 | 8位 | 9位Service-ID |
| CAN ID布局 | v0专用 | v1专用 |
| 单帧Toggle | 0 | 1 |
| 多帧首帧Toggle | 0 | 1 |
| 传输CRC位置 | 数据流开头 | 载荷和填充之后 |
| CRC输入 | 类型签名加载荷 | 载荷加尾部填充 |
即使两者都有Tail byte和5位Transfer-ID,也不能互解。互通需要明确的双协议栈或网关,网关还要转换数据类型、服务语义、状态和错误。
经典CAN与CAN FD¶
Cyphal/CAN可使用:
- 经典CAN,最大传输单元(MTU,Maximum Transmission Unit)为8字节;
- CAN FD,常用MTU为64字节。
扣除Tail byte后,单帧上层载荷分别最多为7和63字节。同一传输网络的节点应采用一致MTU。
CAN FD控制器能够发送经典帧,不表示经典CAN节点能接收FD帧。仅支持经典CAN的活动节点看到FD帧时可能发送错误帧并破坏传输。混用前必须确认所有活动节点和分析仪支持相同模式。
DroneCAN还定义了自己的CAN FD扩展。它仍不是Cyphal/CAN FD;“都使用64字节CAN FD帧”不能建立互操作性。
总线负载¶
CAN负载不能只用载荷字节除以标称速率,因为还包括:
- 仲裁字段;
- 控制、CRC、确认和帧间隔;
- 位填充;
- 扩展标识符开销;
- 多帧Tail byte;
- 传输CRC;
- 错误帧和重发。
应使用实际标识符、数据长度码(DLC,Data Length Code)、速率和捕获时间计算总线占用,并分别观察:
- 平均负载;
- 峰值窗口;
- 高优先级时延;
- 低优先级最坏等待;
- 错误帧;
- 节点发送和接收队列;
- 总线关闭(Bus-off)和恢复。
不存在适用于所有飞控总线的统一安全负载百分比。
节点管理¶
记录:
- 节点ID来源;
- 动态分配或静态配置;
- 重复ID检测;
- 节点名称和软件/硬件版本;
- 数据类型定义提交;
- 启动和健康状态;
- 重启计数;
- 参数或寄存器配置;
- 固件更新路径。
节点ID冲突可能让两台设备同时响应同一服务或使Transfer-ID状态混乱。发现冲突时应停止总线放行。
安全边界¶
传统DroneCAN不提供端到端身份认证或加密。物理接入总线的节点可能:
- 发送更高优先级帧;
- 伪造节点ID;
- 重放旧消息;
- 发起服务请求;
- 耗尽总线;
- 发送合法格式但危险的命令。
需要通过物理隔离、受控网关、消息白名单、速率限制、节点状态门禁和应用层认证降低风险。CAN错误检测不能代替这些措施。
验证步骤¶
执行错误帧、节点ID冲突、异常优先级或负载注入前,必须先完成协议审查与测试卡第0节,并按抓包、解码、一致性与版本迁移在独立测试总线上保存证据。
- 在断电状态确认拓扑、终端和节点;
- 固定所有节点固件、节点ID、比特率和数据类型定义;
- 被动捕获总线启动、稳态和重启;
- 核对29位ID布局、Tail byte和Transfer-ID;
- 对多帧传输重算CRC;
- 验证CRC结果按低字节、再高字节位于数据流开头;
- 核对广播与服务方向;
- 统计负载、仲裁延迟、错误帧和队列;
- 在独立测试总线验证丢帧、重复、错误Toggle、模32回绕和时间状态过期;
- 验证节点重启、动态分配和重复ID处理;
- 如存在v0/v1或Classic/FD网关,分别证明两侧协议和转换失败分支。
禁止在飞行总线或在役设备上注入高优先级洪泛、错误帧、总线关闭或节点ID冲突。
检查理解¶
- CAN链路CRC和DroneCAN传输CRC有什么区别?
- DroneCAN服务为什么不是广播语义?
- Tail byte包含哪些字段?
- DroneCAN与Cyphal为何不能因共用CAN线而视为兼容?
- CAN FD控制器向下兼容为什么不等于经典节点能接收FD帧?