2. CAN FD协议基础:帧结构、数据场长度、位速率切换、BRS与ESI位

做CAN总线相关的项目,你肯定绕不开帧结构这件事。我记得刚接触CAN FD时,第一反应就是「这不就是CAN 2.0加长了数据场吗?」——坦白说,这里面门道比我想象的多不少。

2.1 标准帧 vs 扩展帧:ID位数上的差别

CAN FD继承了经典CAN的两种帧格式:标准帧(11位ID)和扩展帧(29位ID)。差别主要在仲裁场。标准帧的仲裁场只有ID和RTR位;扩展帧则在基本ID后面多了一个SRR位、一个IDE位,再接上18位扩展ID。

帧格式ID长度仲裁场组成控制场中BRS/ESI位置
标准帧11 bitID + RTRIDE = 0, BRS/ESI在控制场第2字节
扩展帧29 bit基本ID + SRR + IDE + 扩展ID + RTRIDE = 1, BRS/ESI位置不变

你想想看,为什么要有扩展帧?因为11位ID最多只有2048个标识符(实际除去保留的,能用的大约2032个),一个复杂的车载网络根本不够用。29位ID能支持5亿多个,基本不存在冲突问题。

个人习惯:我在做诊断协议(UDS on CAN)时,一律用扩展帧。因为诊断请求ID通常要用0x7DF之类的标准帧优先级冲突,用扩展帧可以避开大部分优先级冲突问题。

2.2 数据场长度:从8字节到64字节

经典CAN数据场最大8字节,CAN FD把这个限制直接拉到了64字节。为什么会这样?说白了,软件升级、大数据上传、下一代自动驾驶传感器数据,都需要更大的有效载荷。还是和传统CAN兼容的——你可以在同一个网络上混用CAN 2.0节点和CAN FD节点,只要注意速率切换策略就行。

我个人建议在数据场长度选择上,不要一下子用满64字节。我在试制阶段遇到过一些问题:

  • 发送占时增加:数据场越长,总线占用时间越久(即使位速率提高了)。
  • 接收缓冲区压力:一些低成本MCU的CAN FD硬件FIFO深度不够,连续64字节报文进来会丢帧。
  • CRC校验尾随风险:CAN FD的CRC分为17位(数据场≤16字节)和21位(数据场17~64字节),偶尔遇到21位CRC计算错误但硬件没报错的案例(实际是物料公差)。

核心原则:如果应用场景只需要上传8字节以内的数据,尽量用CAN 2.0模式或CAN FD短数据场,别为了「用新技术」而盲目拉长。

2.3 位速率切换:BRS位的作用

嗯,这里要注意。CAN FD和经典CAN有一个本质差异:仲裁阶段和 数据阶段可以用不同位速率。控制场里的BRS位(Bit Rate Switch)就是这个开关。

  • BRS = 0:全程使用标称位速率(通常1 Mbps以下,仲裁和数据段一样慢)。
  • BRS = 1:仲裁段仍用标称速率(大家慢下来抢总线),但从BRS位之后的数据场+CRC+ACK+EOF部分切换到快速位速率(2~8 Mbps甚至更高)。

我做硬件测试时,发现一个很隐蔽的坑:如果接收节点的采样点设置不对,或者收发器的环路延迟没校准,BRS=1的帧会经常CRC出错。说白了,速率切换要求收发器的上升下降时间、振铃特性必须满足高速模式的要求。

我曾经踩过的坑:客户反馈某款ECU在正常运行中偶尔掉线。查了半天,发现是BRS位翻转瞬间产生了额外的电磁干扰,导致同一网络上的另一节点接收错误。后来把收发器的斜率控制(SLRC)寄存器调低才解决。

2.4 ESI位:错误状态指示

ESI位(Error State Indicator)是CAN FD新增的一个位,放在控制场里。它告诉其他节点:我当前处于什么错误状态?

  • ESI = 0:发送器处于「错误主动」状态——意思是它还能正常收发,错误计数没超过127。
  • ESI = 1:发送器处于「错误消极」状态——错误计数在128~255之间,它只能发送主动错误帧(ACK时不同)等受限能力。

你想想看,这个位有什么用?在传统CAN里,错误消极节点不会把状态告诉别人,只能自己默默退让。CAN FD加入了显式指示,让接收方可以提前规避:比如如果收到ESI=1的报文,我会认为这个节点不可靠,后面它的数据分析可以降低权重或直接丢弃。

实际调试用法:我写了一个小工具,抓取所有CAN FD帧并显示ESI位。如果某节点频繁置ESI=1,说明它硬件或总线供电有问题,可以作为预诊断的依据。

2.5 帧结构总览:一张图看清楚

下面我把标准帧和扩展帧的位级结构画在一起。你可以看到两个帧在仲裁场和控制场的差异,以及BRS、ESI位在控制场中的具体位置。

CAN FD 标准帧(上)与扩展帧(下)位级结构 SOF 11位ID RTR IDE 控制场 BRS/ESI/DLC 数据场 0~64B CRC ACK EOF SOF 基本ID 11位 SRR IDE 扩展ID 18位 RTR 控制场 BRS/ESI/DLC 数据场 0~64B CRC BRS=1时 切换高速 IDE=1 ID/地址段 控制/状态位 控制场(含BRS/ESI) 数据场 CRC / 结束段 速率切换点:BRS=1时,从数据场开始使用快速位速率;BRS=0时,全部使用标称位速率 ESI=1表示发送器处于错误消极状态,接收方可以据此调整处理策略

2.6 一个实战案例:BRS位与仲裁延迟的关系

我在做多节点仲裁延迟仿真时,发现一个规律:当BRS=1的帧和BRS=0的帧同时竞争总线时,BRS=1的帧在仲裁阶段不会因为位速率切换而损失优先级。因为仲裁段的位速率是相同的。但是数据段的高速传输会缩短总线占用时间,从而给其他节点更早释放总线。

说白了,CAN FD的BRS位让「快传慢仲裁」成为可能。如果你想优化整个网络的实时性,建议把高优先级消息(比如扭矩/转速指令)都用BRS=1发送,让它们的数据段尽快结束,低优先级的慢速消息(比如诊断)可以用BRS=0来避免硬件兼容问题。

我个人会这样配置:

  • 所有周期小于5ms的实时信号帧 → BRS=1,数据段速率2 Mbps以上。
  • 所有FOTA升级或配置帧 → BRS=1(64字节数据场加速传输)。
  • 所有兼容性未知的第三方节点 → BRS=0,保守运行。

好了,关于帧结构最核心的基础部分就这些。记住标准帧和扩展帧在ID长度上的区别、BRS位如何控制速率切换、ESI位暴露节点错误状态,后面分析仲裁延迟时你会不断用到这些概念。