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)位

流程是这样的:

  1. 帧起始到 BRS 位之前,所有节点以标称位速率通信(比如 500 kbps)。
  2. BRS 位为隐性(1)时,发送节点切换到数据段位速率(比如 2 Mbps)。
  3. 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 窗口 里看到这个帧的详细信息。注意看 FDFBRS 两个标志位。如果 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 做一致性测试。到时候我会分享一些我在项目里踩过的坑,保证让你少走弯路。