2. CAN总线基础

DroneCAN 与 Cyphal 都构建在经典 CAN 总线之上,因此理解 CAN 的底层行为,是后续调试节点通信、分析总线负载、定位丢帧与错误帧的前提。本节从物理层电气特性出发,逐层向上梳理帧格式、仲裁机制、错误处理与位定时,形成一条完整的“信号—位—帧—仲裁—容错—时序”认知链。

一、物理层:差分信号与终端电阻

经典 CAN 使用两根差分信号线 CAN_H 与 CAN_L,采用“显性位”和“隐性位”两种电平状态。显性位(逻辑 0)驱动总线到约 2.5V 以上的差分电压,隐性位(逻辑 1)差分电压接近 0V。显性位具有“覆盖”隐性位的特性,这正是仲裁机制能够工作的电气基础。

总线两端必须各接一个 120Ω 终端电阻,用于吸收信号反射、稳定差分阻抗。若缺少终端电阻,波形会出现振铃,采样点误判概率显著上升;若只在一端接电阻,阻抗不匹配同样会导致通信不稳定。无人机中常见的 4 针 CAN 接口(CAN_H、CAN_L、GND、VCC)在布线时需保证双绞、等长、短分支。

经验值:1 Mbps 下总线总长度建议不超过 40m;250 kbps 下可到约 250m。分支线(stub)长度应控制在 0.3m 以内,否则反射会破坏位采样。

二、帧格式:标准帧与扩展帧

CAN 2.0B 定义了标准帧(11 位标识符)与扩展帧(29 位标识符)。一帧数据帧主要由以下字段组成:

  • SOF:帧起始,1 个显性位,用于硬同步。
  • 仲裁场:标准帧为 11 位 ID + RTR;扩展帧为 11 位基本 ID + SRR + IDE + 18 位扩展 ID + RTR。
  • 控制场:IDE、r0、DLC(数据长度码,0~8 字节)。
  • 数据场:0~8 字节有效载荷。
  • CRC 场:15 位 CRC + 1 位界定符,用于检错。
  • ACK 场:发送方发隐性位,任一正确接收的节点拉低为显性位表示应答。
  • EOF:7 个隐性位,帧结束。

DroneCAN 使用扩展帧,29 位 ID 中承载了源节点、目标节点、消息类型等信息;Cyphal 同样基于扩展帧,通过 ID 编码优先级、服务/消息类型与节点标识。因此,抓包工具中看到的 ID 并非“地址”,而是被协议层重新解释的复合字段。

三、仲裁机制:非破坏性逐位仲裁

当多个节点同时发送时,CAN 采用 CSMA/CR(载波侦听多路访问/冲突解决)机制。每个节点在发送每一位的同时回读总线电平:若自己发送隐性位而读回显性位,说明有更高优先级节点正在发送,该节点立即退出仲裁,转为接收状态,且不会破坏已获胜帧的数据。

仲裁按 ID 逐位比较,ID 数值越小(显性位越多)优先级越高。这意味着在 DroneCAN/Cyphal 中,优先级字段的设计直接决定了哪些消息在总线拥塞时先被发送。例如,飞控的姿态控制消息通常配置为高优先级,而调试日志类消息配置为低优先级。

CAN 非破坏性逐位仲裁示意 节点 A(ID 0x123,高优先级) SOF ID10 ID9 ID8 ID7 ID6 ID5 ID4 ID3 ID2 ID1 ID0 节点 B(ID 0x1A5,低优先级) SOF ID10 ID9 ID8 ID7 ID6 ID5 ID4 ID3 ID2 ID1 ID0 B 发送隐性、读回显性 → 退出仲裁 总线电平 A 继续发送 A 赢得仲裁,B 转为接收,数据帧未被破坏 ID 数值越小 → 显性位越多 → 优先级越高 仲裁失败节点自动重发,无需上层干预

四、错误处理:五类错误与状态机

CAN 定义了五种错误类型:位错误、填充错误、CRC 错误、格式错误、应答错误。任一节点检测到错误后,会发送错误帧(6 个连续显性位)通知全网,发送方随后自动重发。为限制故障节点持续破坏总线,CAN 引入 TEC(发送错误计数器)与 REC(接收错误计数器),并据此划分三种状态:

状态 进入条件 行为 退出条件
错误主动 Error Active TEC ≤ 127 且 REC ≤ 127 正常收发,可发送主动错误帧 —
错误被动 Error Passive TEC > 127 或 REC > 127 仍可通信,但只发被动错误帧,发送后需额外挂起 TEC 与 REC 均降至 127 以下
总线关闭 Bus Off TEC > 255 主动断开总线,停止收发 检测到 128 次连续 11 个隐性位后恢复
无人机场景中,若某节点反复进入 Bus Off,常见原因是终端电阻缺失、地电位差过大、线缆过长或波特率配置不一致。不要只在上层重发逻辑上找原因。

五、位定时:采样点与同步

CAN 位时间被划分为四个段:同步段(SYNC_SEG)、传播段(PROP_SEG)、相位缓冲段 1(PHASE_SEG1)和相位缓冲段 2(PHASE_SEG2)。采样点位于 PHASE_SEG1 结束处,通常建议设置在位时间的 75%~87.5% 之间。位时间由若干时间份额 Tq 组成,Tq 由系统时钟分频得到。

位时间 = SYNC_SEG + PROP_SEG + PHASE_SEG1 + PHASE_SEG2
       = 1 Tq + PROP_SEG + PHASE_SEG1 + PHASE_SEG2

采样点位置 = (1 + PROP_SEG + PHASE_SEG1) / 总 Tq 数 × 100%

示例(1 Mbps,采样点 87.5%):
  总 Tq = 8
  SYNC_SEG   = 1 Tq
  PROP_SEG   = 2 Tq
  PHASE_SEG1 = 4 Tq
  PHASE_SEG2 = 1 Tq
  采样点 = (1+2+4)/8 = 87.5%

硬同步发生在 SOF 下降沿,使节点位时间对齐;重同步则通过 SJW(同步跳转宽度)在检测到边沿相位误差时微调 PHASE_SEG1 或 PHASE_SEG2。SJW 通常设为 1~4 Tq,过大易受噪声影响,过小则难以补偿晶振偏差。

六、案例与复盘:总线偶发丢帧排查

某四旋翼在 1 Mbps 下偶发 DroneCAN 节点掉线。抓包显示错误帧集中在电机启动瞬间,TEC 快速上升。排查发现:电机电源线与 CAN 双绞线并行捆扎,且飞控端终端电阻未焊接。整改措施:

  1. CAN 线远离动力线,交叉时保持 90°;
  2. 补齐两端 120Ω 终端电阻;
  3. 将采样点从 75% 调整到 87.5%,提高抗反射能力;
  4. 确认所有节点波特率与 SJW 配置一致。

整改后错误帧消失,总线负载稳定在 35% 以下。该案例说明:CAN 的物理层、位定时与错误处理并非孤立知识点,而是共同决定总线可靠性的整体。理解仲裁如何保证高优先级消息优先、错误计数器如何隔离故障节点、采样点如何影响误码率,才能在 DroneCAN 与 Cyphal 开发中快速定位底层问题,而不是停留在协议层反复猜测。