4. CAN FD数据链路层(下):BRS位与ESI位的作用、CAN FD的CRC算法改进(17位/21位CRC)、填充位规则与错误检测
好,咱们接着聊CAN FD的数据链路层。上一节我们把帧结构、速率切换这些基础概念过了一遍。这一节,我打算深入几个关键细节——BRS位、ESI位、CRC算法改进,还有填充位规则和错误检测。
说实话,这些内容在常规的CAN 2.0里是没有的。你如果只是拿CAN FD当普通CAN用,那确实不用关心。但如果你想发挥CAN FD的真正实力,或者你像我一样,在项目里被总线错误折腾过,那这些就是必修课了。
4.1 BRS位:速率切换的“开关”
BRS位,全称是Bit Rate Switch。它只有1个bit,位置在控制场里。它的作用很简单——告诉总线上的所有节点:“我要加速了!”
具体怎么工作的?
- BRS = 0(显性):不切换速率。整个报文都用标称位时间(比如500kbps)传输。
- BRS = 1(隐性):从BRS位之后的数据场开始,切换到高速数据相位(比如2Mbps或更高)。
我刚开始用CAN FD的时候,犯过一个低级错误。我在配置STM32CubeMX时,把BRS位使能了,但接收节点的数据相位速率没配好。结果呢?总线上一跑,接收节点直接报错,整个网络都乱了。后来我学乖了——BRS位不是你想开就能开的,你得确保总线上所有节点都支持同样的高速率。
关键点:BRS位只在数据场生效。仲裁场、控制场、CRC场、ACK场仍然使用标称速率。这样设计是为了保证兼容性——普通CAN节点虽然看不懂数据场,但至少能正确识别帧起始和仲裁过程。
4.2 ESI位:节点的“健康状态”指示灯
ESI位,全称是Error State Indicator。它也是1个bit,同样在控制场里。它的作用是告诉其他节点:“我现在的错误状态怎么样?”
ESI位的取值规则:
- ESI = 0(显性):发送节点处于错误主动状态。也就是说,这个节点状态良好,可以正常发送和接收。
- ESI = 1(隐性):发送节点处于错误被动状态。这个节点已经出过不少错了,它虽然还能发报文,但发送优先级会降低。
你可能会问:“这有什么用?”
嗯,我举个例子。有一次我在调试一个车载网络,发现某个节点时不时丢报文。用CAN分析仪抓包一看,那个节点发送的报文里ESI位一直是1。我立刻意识到——这个节点已经进入错误被动状态了。后来检查发现,是它的终端电阻虚焊了。你看,ESI位就像个健康指示灯,能帮你快速定位问题节点。
个人经验:在开发阶段,我习惯在CAN分析仪上把ESI位单独显示出来。一旦发现某个节点的ESI位频繁置1,我就知道该检查它的硬件或软件了。这比等总线完全崩溃再排查要高效得多。
4.3 CAN FD的CRC算法改进:17位与21位
CRC校验,说白了就是给数据算个“指纹”。接收方收到报文后,重新算一遍CRC,如果和发送方算的不一样,那就说明数据在传输过程中被污染了。
CAN 2.0用的是15位CRC,覆盖范围是帧起始到数据场结束。但CAN FD不一样——它用了更长的CRC,而且覆盖范围也变了。
| CRC类型 | 长度 | 适用场景 | 覆盖范围 |
|---|---|---|---|
| CAN 2.0 CRC | 15位 | 标准CAN | 帧起始 ~ 数据场结束 |
| CAN FD CRC (短数据) | 17位 | 数据场 ≤ 16字节 | 帧起始 ~ 数据场结束 + 填充位计数 |
| CAN FD CRC (长数据) | 21位 | 数据场 > 16字节 | 帧起始 ~ 数据场结束 + 填充位计数 |
为什么CAN FD要用更长的CRC?原因有两个:
- 数据量大了:CAN FD最多能带64字节数据,比CAN 2.0的8字节多了8倍。数据量越大,出错的概率越高,CRC的检错能力必须跟上。
- 速率高了:高速传输时,位时间变短,噪声干扰的影响更明显。更长的CRC能提供更强的检错能力。
我记得第一次用CAN FD传64字节数据时,心里还有点打鼓——21位CRC够不够用?后来查了资料才知道,21位CRC的汉明距离是6,也就是说,它能检测出最多5个随机位错误。对于车载环境来说,这已经非常可靠了。
注意:CAN FD的CRC计算覆盖范围比CAN 2.0多了一个东西——填充位计数。这个后面会讲到。简单说,就是发送方在CRC计算时,把填充位的数量也算进去了。接收方校验时,也会检查填充位数量是否正确。这进一步增强了检错能力。
4.4 填充位规则:CAN FD的“防冲突”机制
填充位规则,是CAN总线的一个经典设计。它的目的是防止总线上出现连续的相同电平,导致节点失去同步。
CAN 2.0的规则很简单:每出现5个连续的相同位,就插入一个相反极性的填充位。
CAN FD的规则基本一样,但有一个重要区别——数据场使用高速率传输时,填充位规则只适用于数据场之前的部分。也就是说,数据场本身不再插入填充位。
为什么会这样?
你想想看,高速传输时,位时间很短。如果还要插入填充位,那发送方和接收方都得额外处理这些填充位,这会增加延迟。而且,高速传输时,总线的电气特性已经变了,连续相同位导致的同步问题没那么严重。所以CAN FD干脆在数据场去掉了填充位。
但这样一来,CRC的覆盖范围就得调整——因为填充位没了,CRC必须覆盖到数据场的每一个bit。这就是为什么CAN FD的CRC覆盖范围包含了填充位计数。
总结一下:
- 仲裁场、控制场、CRC场:仍然使用填充位规则(每5个相同位插入1个相反位)。
- 数据场(高速率):不使用填充位规则。
- 填充位计数:发送方在CRC计算时,把填充位的数量编码进去。接收方校验时,会检查填充位数量是否正确。
4.5 错误检测:CAN FD的“多重保险”
CAN FD的错误检测机制,比CAN 2.0更严格。它用了多重手段来保证数据可靠性:
- 位错误:发送方在发送每个bit时,同时监听总线。如果监听到的电平和发送的不一致,就报位错误。这个机制在CAN 2.0里就有,CAN FD继续沿用。
- 填充错误:接收方检查填充位规则是否被违反。如果连续6个相同位没有填充位,就报填充错误。
- CRC错误:接收方重新计算CRC,如果和发送方的不一致,就报CRC错误。
- 格式错误:如果帧的某个固定格式位(比如CRC分隔符、ACK槽)的电平不对,就报格式错误。
- ACK错误:发送方在ACK槽期间没有收到显性位(即没有节点确认),就报ACK错误。
我印象最深的一次,是在一个实验室环境里测试CAN FD。总线上挂了3个节点,其中一个节点偶尔会发一些奇怪的报文。用CAN分析仪一看,那个节点的报文里CRC错误率特别高。后来发现,是那个节点的晶振精度不够,导致位时间偏差太大。你看,错误检测机制不仅能帮你发现总线问题,还能帮你定位硬件故障。
避坑指南:我曾经在配置STM32CubeMX时,把CAN FD的错误中断全部使能了。结果调试时,终端不停地打印错误信息,根本没法正常工作。后来我学乖了——开发阶段可以全部使能,但正式产品里,只使能必要的错误中断(比如总线关闭中断),其他的错误信息通过轮询方式获取。
4.6 知识结构图:CAN FD数据链路层核心逻辑
下面这张图,把这一节的核心知识点串起来了。你可以把它当作一个快速参考。
4.7 小结
这一节的内容,说白了就是CAN FD在数据链路层的几个关键改进。BRS位让你能灵活切换速率,ESI位帮你监控节点健康状态,CRC算法改进保证了大数据量下的可靠性,填充位规则和错误检测机制则是多重保险。
我个人觉得,理解这些细节,对后续的STM32CubeMX配置很有帮助。比如,你在配置CAN FD时,需要选择CRC长度、使能BRS位、设置错误中断等。如果你不理解这些参数的含义,配置起来就会很盲目。