3. CAN FD 协议进阶:CAN FD 与传统 CAN 的区别、数据场扩展、速率切换与 CRC 增强
好,咱们进入 CAN FD 的部分。说实话,我刚接触 CAN FD 的时候,第一反应是:这不就是 CAN 的升级版吗?后来踩了几个坑才发现,事情没那么简单。
CAN FD,全称是 CAN with Flexible Data-Rate。名字里就透着灵活。它解决了传统 CAN 的两个老大难问题:带宽不够和数据场太小。你想想看,现在一辆车上光一个摄像头的数据量,传统 CAN 的 1Mbps 根本扛不住。所以 Bosch 在 2012 年推出了 CAN FD,后来成了 ISO 11898-1:2015 标准。
3.1 核心区别:CAN FD 到底改了啥?
我习惯把 CAN FD 的改动归纳为三点:数据场扩展、速率切换、CRC 增强。咱们一个一个说。
| 特性 | 传统 CAN | CAN FD |
|---|---|---|
| 最大数据场长度 | 8 字节 | 64 字节 |
| 标称位速率(仲裁段) | 最高 1 Mbps | 最高 1 Mbps(兼容) |
| 数据段位速率 | 同仲裁段 | 最高 8 Mbps(典型 2-5 Mbps) |
| CRC 算法 | 15 位 CRC | 17 位或 21 位 CRC(取决于数据场长度) |
| 帧格式 | 标准帧 / 扩展帧 | 兼容标准帧 / 扩展帧,新增 FDF 标志位 |
| DLC 编码 | 0-8 对应 0-8 字节 | 0-8 对应 0-8 字节,9-15 对应 12/16/20/24/32/48/64 字节 |
你看这个表,最直观的变化就是数据场从 8 字节跳到了 64 字节。但真正让工程师头疼的,是那个速率切换的时机和 CRC 的兼容性问题。
3.2 数据场扩展:DLC 编码的秘密
传统 CAN 的 DLC(Data Length Code)是 4 位,0-8 直接对应字节数。CAN FD 保留了这 4 位,但重新定义了 9-15 的编码。
嗯,这里要注意:DLC 的值和实际字节数不是线性关系。我见过有同事直接写代码把 DLC 设成 10,以为能传 10 个字节,结果解析出来全是乱的。
正确的映射关系是这样的:
| DLC 值 | 传统 CAN 字节数 | 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 |
说白了,DLC=15 的时候,CAN FD 能塞 64 个字节进去。这在传输诊断数据或者固件升级包的时候特别有用。我记得有一次做 OTA 升级,传统 CAN 一个包只能传 8 字节,一个 2MB 的固件要拆成 26 万多个帧,光握手就占了一半时间。换成 CAN FD 之后,同样的数据量,帧数直接降到 3 万出头,效率提升不是一星半点。
3.3 速率切换:BRS 位的妙用
速率切换是 CAN FD 最核心的机制。它靠的是帧里的 BRS(Bit Rate Switch)位。
流程是这样的:
- 帧起始到 BRS 位之前,所有节点以标称位速率通信(比如 500 kbps)。
- BRS 位为隐性(1)时,发送节点切换到数据段位速率(比如 2 Mbps)。
- CRC 分隔符之后,再切回标称位速率。
你可能会问:为什么不全程用高速率?
原因很简单——仲裁需要。传统 CAN 的仲裁机制依赖位时间同步,如果所有位都用高速率,总线上的节点很难在仲裁阶段精确同步。CAN FD 只在数据段提速,仲裁段保持低速,这样既保证了兼容性,又提升了吞吐量。
关键点:BRS 位只在 CAN FD 帧中有效。传统 CAN 帧的 BRS 位是保留位,必须为显性(0)。所以 CAN FD 节点收到传统帧时,不会尝试切换速率。
我在 Vector CANalyzer 里调试的时候,经常用 CAN Statistics 窗口观察速率切换是否成功。如果看到大量的 Bit Stuff Error,十有八九是收发器的速率切换时序没调好。嗯,这里有个坑:有些老款的 CAN 收发器不支持 CAN FD 的快速位速率,换上之后直接报错。我建议你选型的时候,确认一下收发器是否明确标注了「CAN FD Ready」。
3.4 CRC 增强:安全性的升级
数据场大了,速率高了,出错的概率自然也跟着涨。传统 CAN 的 15 位 CRC 在 64 字节数据面前,检错能力有点不够看。所以 CAN FD 引入了两种新的 CRC 多项式:
- 17 位 CRC:用于数据场长度 ≤ 16 字节的帧。
- 21 位 CRC:用于数据场长度 > 16 字节的帧。
而且,CAN FD 的 CRC 计算范围也变了。传统 CAN 只覆盖数据场和部分控制场,CAN FD 的 CRC 覆盖了整个帧从 SOF 到 CRC 场之前的所有位,包括填充位。这就大大降低了漏检率。
我的经验:在 CANalyzer 里,你可以用 CAN FD CRC 计算器 来验证发送端和接收端的 CRC 是否一致。我曾经遇到过一个案例,某个节点在发送 64 字节数据时,CRC 总是算错。后来发现是它的 MCU 的 CRC 硬件模块不支持 21 位多项式,只能用软件模拟,结果时序没跟上。换成硬件 CRC 之后,问题就解决了。
3.5 在 CANalyzer 中验证 CAN FD 帧
说了这么多理论,咱们来点实际的。在 CANalyzer 里,你可以这样配置 CAN FD 的仿真:
// 在 CAPL 中发送一个 CAN FD 帧
variables {
message 0x100 msg_fd;
}
on start {
// 配置为 CAN FD 帧
msg_fd.FDF = 1; // 设置为 CAN FD 格式
msg_fd.BRS = 1; // 启用速率切换
msg_fd.DLC = 15; // 64 字节数据场
msg_fd.byte(0) = 0xAA;
// ... 填充数据 ...
msg_fd.byte(63) = 0x55;
// 发送
output(msg_fd);
}
你可以在 Trace 窗口 里看到这个帧的详细信息。注意看 FDF 和 BRS 两个标志位。如果 FDF=1,说明这是一个 CAN FD 帧;如果 BRS=1,说明数据段使用了高速率。
避坑指南:我曾经在混合网络中(既有 CAN 节点又有 CAN FD 节点)遇到过一个问题:CAN FD 节点发送了 BRS=1 的帧,传统 CAN 节点收到后,因为不理解 BRS 位,直接把它当成保留位处理,结果导致总线错误。解决方案是:在混合网络中,CAN FD 节点必须将 BRS 位设为 0,或者使用 CAN FD 的 透明模式(Transparent Mode),让传统节点忽略 CAN FD 帧。
3.6 小结
CAN FD 不是简单的「提速」,它是在保持向后兼容的前提下,对协议做了一次精准的手术。数据场扩展解决了大数据传输的痛点,速率切换提升了总线利用率,CRC 增强保证了高带宽下的可靠性。
我个人觉得,未来几年 CAN FD 会逐步取代传统 CAN,尤其是在自动驾驶和域控制器架构中。但短期内,混合网络还会存在,所以理解两者的差异和兼容性,是每个总线工程师的必修课。
下一节,咱们聊聊 CAN FD 在 CANalyzer 中的高级分析技巧,包括如何用 CANoe 做一致性测试。到时候我会分享一些我在项目里踩过的坑,保证让你少走弯路。