CAN FD数据帧结构:从SOF到EOF的完整拆解

这一章我们聊聊CAN FD的数据帧结构。说实话,很多工程师对CAN 2.0的帧结构很熟悉,但一到了CAN FD就容易搞混那几个新增的控制位。我刚开始调试CAN FD时,就因为在BRS位上栽过跟头,焊坏了两块板子才弄明白——所以这次咱们一步到位,把每个字段讲透。

CAN FD的数据帧,说白了就是把CAN 2.0的帧结构做了扩展。你想想看,总线速率从1Mbps飙到8Mbps,数据长度从8字节升到64字节,那控制场肯定得重新设计。

CAN FD 数据帧结构总览 SOF 仲裁场 控制场 数据场 CRC场 ACK EOF IDE FDF BRS ESI 关键变化: • CAN FD 在控制场新增了 FDF、BRS、ESI 三个控制位 • CRC 场从 15 位扩展到 17/21 位,保护范围更大 • 数据场从最大 8 字节扩展到 64 字节

SOF — 帧起始

SOF就是一个显性位(逻辑0)。它负责同步总线上的所有节点。我习惯把SOF当作整个帧的“发令枪”——只要总线上出现这个显性电平,所有节点都要重新做硬同步。

重要:SOF本身没有变化。CAN 2.0和CAN FD的SOF完全一样,就是一个显性位。你在解码时不用纠结这个。

仲裁场 — 谁抢到谁说话

仲裁场包含11位(标准帧)或29位(扩展帧)的ID外加1位RTR。CAN FD这边,RTR位被保留但意义变了——CAN FD不支持远程帧。

仲裁的逻辑没变:ID值越小,优先级越高。显性位(0)会覆盖隐性位(1)。我在一个项目中遇到过,两个节点同时发送,ID小的节点赢了仲裁,但解码器死活解不出来——后来发现是ID过滤配置错了。

控制场 — CAN FD的核心变化

控制场是CAN FD的重头戏。所有新特性都体现在这儿了。我们一个个来说。

IDE位(Identifier Extension)

IDE位决定是标准帧(11位ID)还是扩展帧(29位ID)。

  • 0:标准帧
  • 1:扩展帧

这一点跟CAN 2.0完全一样,没改动。

FDF位(FD Format Indicator)

这个位最关键。它告诉总线:我这是一个CAN FD帧,不是传统的CAN 2.0帧。

  • 0(显性):CAN 2.0帧
  • 1(隐性):CAN FD帧

注意:FDF位必须为1才能使用CAN FD的高速数据段和长数据场。如果FDF=0,那后面的BRS和ESI就不存在了,整个帧退化成CAN 2.0。我曾经在配置解码器参数时,看到FDF位是0,但后面的BRS位还赋值了——这不合理,说明发送节点要么不符合规范,要么数据被干扰了。

BRS位(Bit Rate Switch)

BRS位是CAN FD的杀手级特性——它允许在数据段切换比特率。

  • 0(显性):数据段使用标称比特率(跟仲裁段一样)
  • 1(隐性):数据段切换到高速数据比特率

我一般这么理解:仲裁段大家要一起抢总线,所以用1Mbps以下的标称速率;数据段只有发送节点在说话,飙到8Mbps都没问题。

我的习惯:在设计解码参数时,我会把BRS位和采样点设置联动起来。如果BRS=1,那采样点要按高速比特率重新配置——80%的采样点比较稳妥。

ESI位(Error State Indicator)

ESI位反映发送节点的错误状态。

  • 0(显性):发送节点处于错误主动状态(Error Active)
  • 1(隐性):发送节点处于错误被动状态(Error Passive)

你想想看,如果接收节点发现ESI=1,它就能预判:这个节点可能不太可靠,后面的数据我需要更仔细地校验。

数据场 — 从8到64的跨越

CAN FD的数据场长度可以是:0、1、2、3、4、5、6、7、8、12、16、20、24、32、48、64字节,共16种合法长度。注意不是连续的——没有9、10、11这些值。

为什么这么设计?说白了是为了对齐和CRC效率。DLC(数据长度码)映射数据长度的方式变了,我一开始也经常搞混。

DLC值 CAN 2.0数据长度 CAN FD数据长度
0-80-8字节0-8字节
98字节12字节
108字节16字节
118字节20字节
128字节24字节
138字节32字节
148字节48字节
158字节64字节

注意:在CAN FD解码器中,如果看到DLC=9但数据长度只有8字节,说明发送节点没有正确实现CAN FD协议——这在混合网络中偶尔会发生。

CRC场 — 保护范围变了

CRC场是CAN FD和CAN 2.0差异最大的地方之一。

  • CAN 2.0:15位CRC,保护位填充之前的数据
  • CAN FD(<16字节数据):17位CRC
  • CAN FD(≥16字节数据):21位CRC

而且CAN FD的CRC还多了一个CRC定界符。嗯,这里要注意:CAN FD的CRC计算范围覆盖了仲裁场、控制场和数据场,但不包括位填充位。你想想看,如果不小心把填充位算进去,那校验肯定过不了。

我常用的验证方法:用逻辑分析仪抓一个已知数据的CAN FD帧,手动算一遍CRC,跟解码器显示的CRC对比。如果一致,说明采样点和解码参数都没问题。

ACK场 — 确认机制没变

ACK场还是2位:ACK槽 + ACK定界符。发送节点发送隐性位,接收节点如果正确接收则用显性位覆写。这个机制跟CAN 2.0完全一样。

我在调试一个多节点网络时,发现某个节点总是不发ACK。后来查出来是它的ESR(错误状态寄存器)报错了——节点处于Bus Off状态,根本不能参与总线的ACK。所以说,ACK场虽然是2个位,但背后是整个节点的状态管理。

EOF — 帧结束

EOF是7个隐性位。任何节点如果在EOF期间检测到显性位,就会触发填充错误。这样设计是为了防止帧被“斩断”。

实际测试中,我曾经见过总线受干扰时EOF被拉成了显性,结果所有节点都报填充错误,总线直接瘫痪。嗯,这种情况一般要查物理层的终端电阻和共模滤波。

小结:一张表告诉你CAN FD帧内每个字段的职责

字段 位数 职责
SOF1同步启动,硬同步触发
仲裁场11/29ID仲裁,确定发送优先级
控制场(IDE/FDF/BRS/ESI)6标识帧格式、速率切换、错误状态
数据场0-512(64字节×8)用户数据,长度由DLC指定
CRC场17/21+1定界符校验仲裁场到数据场,不含填充位
ACK场2接收节点确认信号
EOF7帧结束定界,防止中断

我个人觉得,理解CAN FD帧结构的关键不是死记每个字段的位数,而是搞清楚两个核心区别:一是控制场多了FDF/BRS/ESI,二是CRC保护范围和长度变了。把这两个点吃透了,解码的时候就不会盲目乱调参数。