CAN FD数据帧结构:从SOF到EOF的完整拆解
这一章我们聊聊CAN FD的数据帧结构。说实话,很多工程师对CAN 2.0的帧结构很熟悉,但一到了CAN FD就容易搞混那几个新增的控制位。我刚开始调试CAN FD时,就因为在BRS位上栽过跟头,焊坏了两块板子才弄明白——所以这次咱们一步到位,把每个字段讲透。
CAN FD的数据帧,说白了就是把CAN 2.0的帧结构做了扩展。你想想看,总线速率从1Mbps飙到8Mbps,数据长度从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-8 | 0-8字节 | 0-8字节 |
| 9 | 8字节 | 12字节 |
| 10 | 8字节 | 16字节 |
| 11 | 8字节 | 20字节 |
| 12 | 8字节 | 24字节 |
| 13 | 8字节 | 32字节 |
| 14 | 8字节 | 48字节 |
| 15 | 8字节 | 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帧内每个字段的职责
| 字段 | 位数 | 职责 |
|---|---|---|
| SOF | 1 | 同步启动,硬同步触发 |
| 仲裁场 | 11/29 | ID仲裁,确定发送优先级 |
| 控制场(IDE/FDF/BRS/ESI) | 6 | 标识帧格式、速率切换、错误状态 |
| 数据场 | 0-512(64字节×8) | 用户数据,长度由DLC指定 |
| CRC场 | 17/21+1定界符 | 校验仲裁场到数据场,不含填充位 |
| ACK场 | 2 | 接收节点确认信号 |
| EOF | 7 | 帧结束定界,防止中断 |
我个人觉得,理解CAN FD帧结构的关键不是死记每个字段的位数,而是搞清楚两个核心区别:一是控制场多了FDF/BRS/ESI,二是CRC保护范围和长度变了。把这两个点吃透了,解码的时候就不会盲目乱调参数。