CAN FD 核心特性:数据场扩展与可变速率

好,咱们直接进入正题。CAN FD 相比传统 CAN 2.0,最直观的变化就是四个字:更快、更多。但背后牵涉的协议细节,才是我们做移植时要啃的硬骨头。我个人习惯把这四个核心特性拆开来讲,这样你理解起来会清晰很多。

CAN FD 四大核心特性速览
  • 数据场扩展:从 8 字节 → 64 字节
  • 可变速率(BRS):仲裁段与数据段使用不同波特率
  • 新的 DLC 编码规则:0~15 对应不同字节长度
  • CRC 增强:17 位或 21 位 CRC,覆盖更多数据

数据场扩展:从 8 字节到 64 字节

传统 CAN 一帧最多带 8 个字节数据。这在早期够用,但现在一个 ECU 固件升级包动不动几十 KB,8 字节一帧地传,效率太低了。CAN FD 直接把数据场上限拉到 64 字节。

我在项目中遇到过这样一个场景:做 OTA 升级时,传统 CAN 每帧只能塞 8 字节,加上协议头、序列号、校验,实际有效数据更少。换成 CAN FD 后,一帧 64 字节,传输效率提升了 5~6 倍。嗯,这个提升是实打实的。

特性 传统 CAN CAN FD
数据场最大长度 8 字节 64 字节
有效载荷提升 基准 8 倍
典型应用 控制信号、传感器值 固件升级、日志上传
我的建议:移植协议栈时,先确认你的 MCU 的 CAN FD 控制器是否支持 64 字节收发。STM32G4/H7 系列基本都支持,但有些早期型号只支持到 48 字节。

可变速率(BRS):仲裁慢、数据快

为什么需要可变速率?你想想看,CAN 总线上挂着几十个节点,仲裁阶段必须所有节点都能同步,所以波特率不能太高,通常 500 kbps 或 1 Mbps。但数据阶段只有发送方和接收方在通信,这时候完全可以跑得更快。

CAN FD 的 BRS(Bit Rate Switch)机制就是干这个的。仲裁段用标准速率,数据段切换到高速率,最高可达 8 Mbps 甚至更高。说白了,就是「慢点抢,快点传」。

我曾经踩过的坑:BRS 切换时,如果接收端的 PLL 锁相环响应不够快,会导致数据段前几个位采样错误。解决办法是在数据段开头加一段同步位序列,或者降低数据段速率到 4 Mbps 以内。

新的 DLC 编码规则

传统 CAN 的 DLC(数据长度码)是 4 位,0~8 直接对应字节数。CAN FD 的 DLC 也是 4 位,但编码规则变了。0~8 还是对应 0~8 字节,但 9~15 被重新映射到 12、16、20、24、32、48、64 字节。

这个映射关系必须记清楚。我见过有人直接把 DLC=9 当成 9 字节用,结果接收端解析出来的数据全是乱的。

DLC 值 传统 CAN 字节数 CAN FD 字节数
0~80~80~8
9812
10816
11820
12824
13832
14848
15864
编码规则速记:DLC 0~8 照旧,9~15 对应 12、16、20、24、32、48、64。你可以在协议栈里写一个查表函数,避免每次计算。

CRC 增强:17 位与 21 位

数据量大了,校验也得跟上。传统 CAN 用 15 位 CRC,覆盖 0~8 字节数据。CAN FD 根据数据场长度选择不同的 CRC 多项式:

  • 17 位 CRC:数据场 ≤ 16 字节时使用
  • 21 位 CRC:数据场 20~64 字节时使用

为什么分两档?因为 CRC 生成多项式越长,计算开销越大。对于短帧,用 21 位 CRC 纯属浪费 CPU 周期。我建议在协议栈初始化时,根据你项目中最常用的数据长度,预计算 CRC 表,这样运行时直接查表,速度会快很多。

避坑指南:CAN FD 的 CRC 计算覆盖范围包括数据场、填充位、甚至部分控制位。移植时一定要确认你的硬件 CRC 模块是否支持 CAN FD 的生成多项式。如果不支持,就得用软件算,那就要注意实时性了。

知识体系总览

下面这张图把四个核心特性的关系串起来了。你可以看到,数据场扩展是基础,BRS 是提速手段,DLC 编码是适配规则,CRC 增强是安全保障。四者缺一不可。

CAN FD 核心特性关系图 CAN FD 协议 数据场扩展 8B → 64B 可变速率 BRS 仲裁慢·数据快 DLC 新编码 0~15 映射表 CRC 增强 17/21 位 核心逻辑说明 • 数据场扩展是基础,没有 64 字节,其他特性无从谈起 • BRS 是提速手段,仲裁段保兼容,数据段提效率 • DLC 编码是适配规则,保证新旧协议兼容 • CRC 增强是安全保障,数据量越大,校验越重要

移植时的注意事项

这四个特性在协议栈移植时,会直接影响你的代码结构。我个人习惯按以下顺序处理:

  1. 先确认硬件能力:你的 STM32 CAN FD 控制器是否支持 64 字节、BRS、以及 21 位 CRC 生成。
  2. 配置 DLC 映射表:在协议栈初始化阶段,把 DLC 到字节数的映射表写死,避免运行时计算。
  3. 实现 BRS 切换逻辑:发送时根据数据长度决定是否置位 BRS 标志,接收时根据 BRS 位切换采样时钟。
  4. 选择 CRC 算法:如果硬件支持,直接配置寄存器;如果不支持,用软件查表法实现 17/21 位 CRC。
重要提醒:CAN FD 和传统 CAN 可以在同一条总线上共存,但前提是传统节点不能识别 CAN FD 帧的 BRS 位和扩展数据场。如果总线上有传统节点,CAN FD 节点发送时必须使用 FD 格式,否则传统节点会报错。这个兼容性问题,我在项目初期就吃过亏。