2. CAN总线基础

CAN Bootloader 的可靠性,最终取决于对 CAN 总线底层行为的理解。升级过程中出现的“刷写失败”“节点无响应”“偶发丢包”,往往不是 Bootloader 逻辑错误,而是帧格式、仲裁、位定时或物理层配置不匹配导致的。本节把 CAN 协议中最影响 Bootloader 升级的五个要点串起来:帧格式、仲裁机制、位定时、错误处理与物理层。

一、CAN 帧格式:升级数据如何被封装

CAN 2.0B 定义了四种帧类型:数据帧、远程帧、错误帧和过载帧。Bootloader 升级主要使用数据帧,其标准格式(11 位标识符)结构如下:

字段长度作用
SOF1 位帧起始,显性位,用于硬同步
标识符 ID11 位(标准)/29 位(扩展)标识报文内容与优先级
RTR1 位0 为数据帧,1 为远程帧
IDE1 位0 为标准帧,1 为扩展帧
DLC4 位数据长度,0~8 字节
Data0~8 字节实际载荷,升级时承载固件数据
CRC15 位帧校验,错误则触发错误帧
ACK2 位接收节点拉低确认
EOF7 位帧结束,隐性位序列

在 Bootloader 中,通常把 ID 划分为“功能 ID”和“数据 ID”:例如 0x7A0 用于握手与命令,0x7A1 用于固件数据块。DLC 固定为 8 可提高传输效率,但要注意最后一帧可能不足 8 字节,需用填充字节补齐并在协议层记录真实长度。

二、仲裁机制:为什么升级命令不会被数据淹没

CAN 采用非破坏性逐位仲裁:多个节点同时发送时,显性位(0)覆盖隐性位(1)。ID 数值越小,优先级越高。发送节点在每一位回读总线,若发现自己发送隐性却读到显性,立即退出仲裁转为接收,且不产生错误。

这对 Bootloader 非常关键:升级握手、擦除、跳转等控制命令应分配较小 ID,固件数据块分配较大 ID。这样即使总线上有大量数据帧,控制命令仍能优先获得总线,避免升级流程被数据流“饿死”。

仲裁失败不是错误,不会增加错误计数器。Bootloader 状态机应把“发送失败但仲裁丢失”视为正常重试,而不是通信故障。

三、位定时:采样点与波特率必须一致

CAN 位时间由同步段(Sync_Seg)、传播段(Prop_Seg)、相位缓冲段 1(Phase_Seg1)和相位缓冲段 2(Phase_Seg2)组成,以时间份额 Tq 为单位。采样点位于 Phase_Seg1 结束处,通常建议在 75%~87.5% 之间。

位时间 = Sync_Seg + Prop_Seg + Phase_Seg1 + Phase_Seg2
Tq     = 1 / (f_osc / 分频系数)
波特率 = 1 / 位时间

示例:f_osc = 8 MHz,分频 = 4,Tq = 0.5 us
位时间 = 16 Tq = 8 us  →  波特率 = 125 kbps
采样点 = (1 + 14) / 16 = 87.5%

Bootloader 升级前必须确认上位机、目标 ECU 和总线其他节点的波特率与采样点一致。常见误区是只对齐波特率而忽略采样点:在长线束或高负载下,采样点偏差会导致偶发位错误,表现为“升级到 80% 突然失败”。

四、错误处理:错误帧与节点状态

CAN 节点维护发送错误计数器 TEC 和接收错误计数器 REC,并据此进入三种状态:

  • 错误主动(Error Active):TEC 和 REC 均小于 128,可正常发送主动错误帧。
  • 错误被动(Error Passive):任一计数器超过 127,仍可通信,但只能发送被动错误帧。
  • 总线关闭(Bus Off):TEC 超过 255,节点自动脱离总线,停止收发。

Bootloader 必须处理 Bus Off:检测到后应执行恢复流程(等待 128 次 11 位隐性位,或软件复位 CAN 控制器),并向上位机上报错误码。否则节点会“假死”,上位机只能看到超时。

升级过程中若目标 ECU 进入 Bus Off,不要立即重刷。应先读取错误计数器与总线负载,确认是线束、终端电阻还是波特率问题,否则重刷只会重复失败。

五、物理层要点:差分、终端与拓扑

CAN 物理层采用差分信号 CAN_H 与 CAN_L,显性位差分电压约 2 V,隐性位约 0 V。关键要点:

  • 总线两端各接一个 120 Ω 终端电阻,中间节点不接,否则阻抗不匹配导致反射。
  • 采用手拉手总线拓扑,避免星形或长分支,分支长度建议小于 0.3 m。
  • 波特率与最大总线长度相关:125 kbps 约 500 m,250 kbps 约 250 m,500 kbps 约 100 m,1 Mbps 约 40 m。
  • 共地参考:CAN 收发器需要共地,长距离时建议使用隔离收发器。

下面用一张信号链示意图把“上位机—收发器—双绞线—目标 ECU”的物理连接与终端电阻位置画清楚:

CAN 物理层信号链与终端电阻 上位机 / PC USB-CAN 适配器 CAN_H / CAN_L 收发器 TJA1050 CAN_H CAN_L 120 Ω 120 Ω 收发器 TJA1050 目标 ECU MCU + CAN Bootloader 显性位:CAN_H ≈ 3.5 V,CAN_L ≈ 1.5 V,差分 ≈ 2 V 隐性位:CAN_H ≈ CAN_L ≈ 2.5 V,差分 ≈ 0 V

六、案例与复盘:一次升级失败的分析

某项目在台架上升级正常,装车后升级到 60% 频繁失败。排查发现:整车 CAN 总线长度约 12 m,但只在 ECU 端接了一个 120 Ω 电阻,上位机端未接;同时采样点配置为 62.5%,低于推荐值。整改后两端各接 120 Ω,采样点调整为 80%,升级成功率恢复至 100%。

复盘结论:Bootloader 升级问题中,物理层与位定时问题占比往往高于协议逻辑问题。先量终端电阻、再测波形、最后查采样点,是高效的排障顺序。

把本节要点落到 Bootloader 工程上,可以形成一张检查清单:

  1. 确认所有节点波特率、采样点一致,建议采样点 75%~87.5%。
  2. 控制命令使用小 ID,数据块使用大 ID,保证仲裁优先级合理。
  3. DLC 固定 8 字节,协议层记录真实数据长度。
  4. Bootloader 必须处理 Bus Off 与错误被动状态,并上报错误码。
  5. 总线两端各一个 120 Ω 终端电阻,避免星形拓扑与长分支。

理解这些底层机制后,后续设计 CAN Bootloader 的帧协议、超时重传与状态机时,才能把“能升级”变成“稳定升级”。