第2章:CAN FD协议详解:帧结构、速率分离与CRC校验

好,咱们接着聊CAN FD。上一章我讲了CAN FD为什么会出现,说白了就是传统CAN太慢了,8个字节的数据量在今天的汽车电子场景下根本不够用。这一章,咱们深入看看CAN FD的帧结构到底长什么样。

我个人习惯,学任何协议先看帧结构。帧结构就是协议的“骨架”,骨架搭明白了,后面的仲裁、错误处理、实时性分析才能站得住脚。

2.1 标准帧与扩展帧:ID长度决定一切

CAN FD保留了传统CAN的两种帧格式:标准帧(11位ID)和扩展帧(29位ID)。这一点没变,但要注意的是——CAN FD的帧控制段做了重新设计

先看标准帧的结构:

SOF | 11位ID | RTR | IDE | r0 | BRS | ESI | DLC | 数据段 | CRC | ACK | EOF

再看扩展帧:

SOF | 11位ID | SRR | IDE | 18位ID | RTR | r1 | r0 | BRS | ESI | DLC | 数据段 | CRC | ACK | EOF

嗯,这里要注意几个关键变化:

  • r0/r1位:在传统CAN里是保留位,CAN FD里被重新定义了
  • BRS位:这是CAN FD的灵魂,后面细说
  • ESI位:错误状态指示,新加的

我在项目中遇到过一个问题:有人把CAN FD节点配成了11位标准帧,但总线上的网关只支持扩展帧。结果呢?仲裁阶段直接ID冲突,整个网络乱套。所以我的建议是——设计阶段就定好ID格式,别混用

2.2 BRS位与ESI位:速率分离的开关

这是CAN FD最核心的改进。咱们一条一条说。

BRS位(Baud Rate Switch)

BRS位的作用很简单:告诉所有节点,数据段我要加速了

具体机制是这样的:

  • BRS = 0:数据段速率 = 仲裁段速率(传统模式)
  • BRS = 1:数据段速率 = 高速模式(通常2-8 Mbps)

你想想看,为什么能这么做?因为仲裁段需要所有节点同步,必须用慢速。但数据段只有一个节点在发,完全可以跑快一点。

关键点:BRS位位于控制段,在DLC之前。接收节点读到BRS=1后,会立即切换采样点频率。这个切换必须在几个bit时间内完成,对PHY层要求很高。

我曾经调试过一个项目,BRS位切换后数据段跑8Mbps,结果总线上有3个节点收不到数据。查了半天,发现是其中一颗收发器的上升沿时间不够快,跟不上速率切换。换了一颗支持CAN FD的收发器,问题解决。

ESI位(Error State Indicator)

ESI位是CAN FD新增的,用来指示发送节点的错误状态:

  • ESI = 0:发送节点处于“错误主动”状态
  • ESI = 1:发送节点处于“错误被动”或“总线关闭”状态

这个位有什么用?我举个例子:假设总线上有个节点开始频繁出错,它会从“错误主动”降级为“错误被动”。这时候它发的每一帧都会把ESI位置1。其他节点看到ESI=1,就知道“这家伙不太靠谱”,可以提前做容错处理。

小技巧:在诊断工具里,我习惯把ESI位的变化作为一个监控指标。如果某个节点频繁出现ESI=1,基本可以判定它的硬件有问题,或者受到了严重干扰。

2.3 仲裁段与数据段速率分离

说白了,CAN FD就是把一帧分成了两段,用两种速度跑。

范围 典型速率 特点
仲裁段 SOF ~ BRS位(含) 500 kbps 所有节点参与仲裁,必须同步
数据段 BRS位之后 ~ CRC结束 2-8 Mbps 只有发送节点在发,可以加速
ACK段 CRC之后 ~ EOF 回到仲裁段速率 接收节点需要同步应答

为什么ACK段要降回慢速?因为ACK段需要所有接收节点同时发送应答位,这又回到了“多节点同时发送”的场景,必须用仲裁段速率来保证同步。

我刚开始做CAN FD设计时,犯过一个低级错误:把数据段速率设成了10Mbps,但收发器只支持到5Mbps。结果数据段全是CRC错误。后来我学乖了——先查收发器的datasheet,再定速率

2.4 CAN FD的CRC校验:更长的保护

数据段跑快了,误码率自然上升。所以CAN FD的CRC做了强化。

传统CAN的CRC是15位,多项式是:

x^15 + x^14 + x^10 + x^8 + x^7 + x^4 + x^3 + 1

CAN FD的CRC分两种:

  • 17位CRC:用于数据长度 ≤ 16字节
  • 21位CRC:用于数据长度 20-64字节

多项式分别是:

17位:x^17 + x^16 + x^14 + x^13 + x^11 + x^6 + x^4 + x^3 + x^2 + 1
21位:x^21 + x^20 + x^18 + x^17 + x^15 + x^14 + x^13 + x^12 + x^10 + x^9 + x^8 + x^6 + x^4 + x^3 + 1

为什么这么设计?因为数据段长了,15位CRC的汉明距离不够。CAN FD的17/21位CRC能保证在64字节数据下,汉明距离仍然≥6。

注意:CRC的计算范围包括:数据段 + 填充位(stuff bits)。这一点和传统CAN不同。传统CAN的CRC只覆盖数据段,不包含填充位。CAN FD把填充位也纳入了CRC保护,进一步降低了漏检率。

2.5 填充规则:不一样的stuffing

传统CAN的填充规则很简单:连续5个相同电平后,插入一个相反电平的填充位。

CAN FD的仲裁段沿用这个规则。但数据段不一样——数据段采用“固定填充”或“无填充”模式

具体来说:

  • 仲裁段:传统填充规则(5个相同位后插入)
  • 数据段:固定填充(每4个位后插入一个填充位)

为什么要改?因为数据段速率高,传统填充规则会导致填充位位置不确定,增加接收端的同步难度。固定填充让填充位的位置可预测,接收端更容易恢复时钟。

我遇到过一个问题:某个CAN FD控制器在数据段用了传统填充规则,结果在高速率下频繁出现位填充错误。后来查勘手册,发现是控制器不支持数据段固定填充。换了一颗支持CAN FD 2.0的控制器,问题消失。

避坑指南:选型时一定要确认控制器是否支持CAN FD的数据段固定填充。有些老芯片只支持传统填充,跑不了高速。

2.6 小结

这一章咱们把CAN FD的帧结构拆了个遍。核心就三点:

  1. BRS位是速率分离的开关,决定了数据段能不能跑快
  2. ESI位是节点的“健康指示灯”,方便诊断
  3. CRC和填充规则都做了强化,为了应对高速率下的可靠性挑战

下一章,咱们聊聊CAN FD的实时性分析。说白了就是:数据段跑快了,但仲裁段还是慢的,那整个系统的延迟到底怎么算?