1. CAN FD 协议基础:从 CAN 2.0 到 CAN FD 的进化

各位同学,咱们直接进入正题。CAN FD 这玩意儿,说白了就是 CAN 2.0 的升级版。我最早接触 CAN 总线是在做车载诊断模块的时候,那时候还是经典的 CAN 2.0B,跑 500 kbps,一帧最多带 8 个字节数据。后来项目要求升级固件 OTA,8 个字节根本不够用,这才开始研究 CAN FD。

嗯,咱们先搞清楚一个核心问题:为什么要有 CAN FD?

传统 CAN 2.0 的瓶颈很明显:

  • 数据场最多 8 字节,传个 Bootloader 得拆成几百帧
  • 整帧都用同一个位速率,仲裁段和数据段速度一样
  • 没有错误状态反馈,出了问题只能靠超时判断

CAN FD 就是来解决这些问题的。它向下兼容 CAN 2.0,但多了几个关键能力。

1.1 CAN 2.0 与 CAN FD 的核心区别

我习惯用一张表来对比,这样最直观。你在项目选型时,这张表能帮你快速判断该用哪种协议。

对比项 CAN 2.0 (经典 CAN) CAN FD (灵活数据速率)
最大数据场长度 8 字节 64 字节
位速率 整帧固定(通常 ≤1 Mbps) 仲裁段 ≤1 Mbps,数据段最高 8 Mbps
帧格式 标准帧 / 扩展帧 兼容 CAN 2.0 + FD 帧(带 BRS/ESI)
DLC 编码 0~8 对应 0~8 字节 0~8 对应 0~8 字节,9~15 对应 12/16/20/24/32/48/64 字节
CRC 15 位 CRC 17 位(≤16 字节)或 21 位(>16 字节)
错误状态指示 无 ESI 位,发送节点主动上报错误状态

关键点:CAN FD 的物理层和 CAN 2.0 完全一样。也就是说,你现有的 TJA1044 收发器可以直接用在 CAN FD 网络上,不需要换硬件。这一点我在项目中验证过多次,放心用。

1.2 CAN FD 帧结构详解

咱们来看 CAN FD 的帧结构。它和 CAN 2.0 长得像,但多了几个关键位。我画了一张图,你一看就明白。

CAN FD 帧结构(数据帧) SOF 仲裁段 ID + RTR + IDE 控制段 DLC + BRS + ESI 数据段 0~64 字节 CRC 段 17/21 位 CRC ACK EOF BRS = 1 切换高速 帧结构说明: • SOF(帧起始):1 个显性位,同步所有节点 • 仲裁段:11 位 ID(标准帧)或 29 位 ID(扩展帧),决定总线优先级 • 控制段:DLC 编码数据长度,BRS 控制位速率切换,ESI 指示发送节点错误状态 • 数据段:实际传输的数据,CAN FD 最多 64 字节

你注意看控制段里的三个关键位:DLC、BRS、ESI。这三个位是 CAN FD 的灵魂。咱们一个一个拆开讲。

1.3 数据场长度编码(DLC)

DLC 在 CAN 2.0 里很简单:0~8 对应 0~8 字节。但 CAN FD 不一样,它用了 4 位 DLC 编码,可以表示更大的数据长度。

我刚开始看这个表的时候也愣了一下——为什么 9~15 不连续对应 9~15 字节?后来才明白,这是为了兼容 CAN 2.0 的 DLC 编码,同时用剩余编码值映射到更大的数据长度。

DLC 值(4 位) CAN 2.0 数据长度 CAN FD 数据长度
0 ~ 8 0 ~ 8 字节 0 ~ 8 字节
9 8 字节 12 字节
10 8 字节 16 字节
11 8 字节 20 字节
12 8 字节 24 字节
13 8 字节 32 字节
14 8 字节 48 字节
15 8 字节 64 字节

实战经验:我在做 Bootloader 升级时,用 DLC = 15 传 64 字节数据帧,配合 4 Mbps 的数据段速率,一秒钟能传大约 3 MB 数据。相比传统 CAN 2.0 的 500 kbps、每帧 8 字节,速度提升了将近 50 倍。这个提升在 OTA 场景下非常明显。

1.4 位速率切换(BRS)

BRS 位是 CAN FD 最巧妙的设计。它允许在一帧内部切换位速率。

为什么会这样?你想想看,CAN 总线的仲裁过程需要所有节点同步,所以仲裁段必须用慢速。但数据段传输的是有效载荷,不需要仲裁,完全可以跑快一点。

BRS 的工作逻辑:

  • BRS = 0:整帧使用仲裁段速率(兼容 CAN 2.0)
  • BRS = 1:从 BRS 位之后切换到高速数据段,直到 CRC 段结束再切回

我习惯这么配置:

  • 仲裁段:500 kbps(保证兼容性和抗干扰)
  • 数据段:2 Mbps ~ 5 Mbps(根据线缆长度和节点数调整)

注意:数据段速率不是越高越好。我在一个项目中试过 8 Mbps,结果线缆超过 40 cm 就开始丢帧。后来降到 4 Mbps,配合 TJA1044 的显性超时功能,才稳定下来。建议你先从 2 Mbps 起步,用示波器看眼图,再逐步提高。

1.5 错误状态指示(ESI)

ESI 位是 CAN FD 新增的,用来让发送节点主动告诉接收方:「我现在状态不太好」。这在 CAN 2.0 里是没有的。

ESI 的三种状态:

  • 错误主动(Error Active):ESI = 0,节点正常工作,可以主动发送错误帧
  • 错误被动(Error Passive):ESI = 1,节点发送错误计数 ≥ 128,只能发送被动错误帧
  • 总线关闭(Bus Off):节点彻底离线,不参与任何通信

我记得有一次调试,发现某个节点间歇性丢帧。用 CAN 分析仪抓包,看到 ESI 位频繁置 1。一查,原来是那个节点的终端电阻虚焊,导致信号反射严重,错误计数飙升。修好电阻后,ESI 恢复正常。

实用技巧:在 STM32 的 CAN FD 驱动中,你可以配置中断来捕获 ESI 状态变化。一旦发现 ESI = 1,立即记录错误计数并报警。这比等总线离线再处理要主动得多。

1.6 本章小结

咱们把这一章的核心点串一下:

  • CAN FD 向下兼容 CAN 2.0,物理层不变
  • 数据场从 8 字节扩展到 64 字节,DLC 编码用 4 位映射
  • BRS 位实现仲裁段低速 + 数据段高速的混合速率
  • ESI 位让节点主动上报错误状态,方便诊断