CAN FD 与经典 CAN 的对比
做嵌入式通信这么多年,我接触最多的总线就是 CAN。早期产品全是经典 CAN 2.0,后来遇到一个项目需要同时上传大量传感器数据和诊断信息,经典 CAN 的 8 字节载荷限制把整个团队折腾得够呛。换 CAN FD 之后,数据量上去了,速率也快了,关键可靠性一点没降。这一章我就把这两兄弟放在一起仔细比比,带你看看它们到底差在哪儿。
帧格式差异
帧格式是第一个肉眼可见的区别。经典 CAN 只有标准帧(11 位 ID)和扩展帧(29 位 ID),CAN FD 在扩展帧的基础上加了几个新位:EDL(Extended Data Length)、BRS(Bit Rate Switch)、ESI(Error State Indicator)。
- EDL 位:位于控制场,置 1 表示这是 CAN FD 帧,不是经典 CAN 帧。说白了就是一个“我是谁”的标志。
- BRS 位:置 1 时允许数据场使用更高的传输速率,仲裁段之后瞬间提速。
- ESI 位:发送节点错误状态指示,接收方可以知道对方是否已经进入 passive 状态。
我个人习惯把帧格式画成一张对比图,一眼就看出差异点。下面这张 SVG 图把经典 CAN 和 CAN FD 的帧结构并排展示,关键位用不同颜色标出来了。
避坑指南:我曾经在写 CAN FD 驱动时忘了处理 BRS 位,导致数据场速率切换失败,整个通信链路卡死在仲裁段速率。后来加上正常的速率切换时序才搞定。
速率提升
经典 CAN 最高速率 1 Mbps,这是由仲裁机制和位时序决定的。CAN FD 把数据段的速率提高到最高 8 Mbps(某些实现甚至更高)。
- 仲裁段:仍然使用经典 CAN 的速率(最高 1 Mbps),保证与非 FD 节点的兼容。
- 数据段:BRS 位为 1 时,发送节点在数据场和 CRC 场切换到高速,结束后切回仲裁速率。
- 实际效果:有效负载传输时间大幅缩短。同一网络下,经典 CAN 传 8 字节数据约需 100 μs,CAN FD 传 64 字节仅需约 300 μs(8 Mbps 数据段)。
| 对比项 | 经典 CAN | CAN FD |
|---|---|---|
| 最大仲裁速率 | 1 Mbps | 1 Mbps(兼容) |
| 最大数据速率 | 1 Mbps(无区分) | 最高 8 Mbps(典型 5-8 Mbps) |
| 速率切换点 | 无 | 数据场开始处,BRS 位控制 |
| 总线利用率 | 中 | 高(尤其大包传输) |
为什么会这样?经典 CAN 的位时间必须满足整个网络的同步要求,不能随便提速。CAN FD 通过“仲裁段固定速率 + 数据段可变速率”的方式,既保证了总线上的节点都能参与仲裁,又让大数据场能跑得飞快。你想想看,一个 64 字节的报文用经典 CAN 要拆成 8 帧发送,光仲裁开销就够受的。CAN FD 一帧搞定,效率自然上去了。
数据长度扩展
这是很多工程师最直接的感受。经典 CAN 的数据场只有 0-8 字节,CAN FD 扩展到 0-64 字节。DLC(数据长度码)的编码方式也变了。
- 经典 CAN:DLC 4 位,编码 0-8,9-15 保留。
- CAN FD:DLC 4 位,但 9-15 映射到实际长度:9→12、10→16、11→20、12→24、13→32、14→48、15→64。注意不是线性映射,而是一种“阶梯增长”。
我建议你在选择数据长度时,优先使用 8、16、32、64 这些对齐边界。某些 MCU 的 DLC 解码逻辑对非对齐长度(比如 12、20、24、48)处理起来会有额外的字节填充,影响效率。
我在一个车载网关项目里遇到过这个坑:一个节点发送 48 字节,另一个节点收到后发现尾部有诡异的 0x00。后来查手册,原来某些控制器要求 DLC 对应的字节数必须 4 字节对齐,发 48 字节没问题,但接收端会把多出来的填充字节当作有效数据。嗯,这里要注意——如果你用的 MCU 文档没提对齐要求,最好自己验证一下。
可靠性增强
数据量大了、速率快了,可靠性怎么保证?CAN FD 主要在 CRC 上做了强化。
- 经典 CAN:15 位 CRC,多项式 x15 + x14 + x10 + x8 + x7 + x4 + x3 + 1。覆盖 SOF、仲裁场、控制场、数据场。
- CAN FD:根据数据场长度选择 17 位或 21 位 CRC,多项式更复杂,保护能力更强。同时 CRC 计算覆盖的范围增加了 EDL、BRS、ESI 位。
| 场景 | 经典 CAN CRC | CAN FD CRC |
|---|---|---|
| 数据场 ≤ 8 字节 | 15 位 | 17 位 |
| 数据场 12-64 字节 | 不支持 | 21 位 |
| 覆盖范围 | 标准帧/扩展帧 | 扩展帧 + FD 控制位 |
除了 CRC,CAN FD 还引入了双重 ACK 槽(其实不是两个槽,而是接收节点在 ACK 场同时确认两件事:帧有效性和 CRC 正确性)。这样做的好处是减少了错帧漏检的概率。我曾经用示波器抓过经典 CAN 的隐蔽错误——一个位翻转导致 CRC 校验未通过但 ACK 却正确发出,节点误以为是有效帧。CAN FD 的双重确认机制基本杜绝了这个情况。
注意:CAN FD 的 ESI 位可以让接收节点了解发送节点的错误状态。但前提是发送节点必须正确维护错误计数器。如果错误计数器溢出导致 bus off,ESI 位就不再可信了。