4、CAN FD帧结构详解:标准帧与扩展帧区别、BRS位与ESI位作用、CRC计算(17位/21位)、填充位规则(0/1交替)

好,咱们进入第四章。这一章我打算把CAN FD的帧结构彻底拆开来讲。说实话,很多工程师用了好几年CAN,对帧结构还是一知半解。尤其是CAN FD引入的那些新玩意儿——BRS位、ESI位、还有那让人头疼的CRC计算。别急,我一个一个给你捋清楚。

4.1 标准帧 vs 扩展帧:不只是ID长度不同

先说说最基础的区别。标准帧的ID是11位,扩展帧是29位。这个大家都知道。但我在项目里发现,很多人以为扩展帧就是把标准帧的ID拉长而已。其实没那么简单。

你想想看,CAN总线上同时跑标准帧和扩展帧的时候,仲裁机制是怎么处理的?标准帧的IDE位是显性(0),扩展帧的IDE位是隐性(1)。仲裁时,显性优先。所以标准帧的优先级天然高于扩展帧——哪怕扩展帧的ID数值更小。

我遇到过这样一个坑:有一次调试一个混合网络,标准帧和扩展帧混用。结果发现某个扩展帧的高优先级消息总是被标准帧的低优先级消息抢了总线。查了半天,原来是IDE位在作怪。从那以后,我建议团队:要么全用标准帧,要么全用扩展帧,别混着用。除非你很清楚仲裁的后果。

关键区别总结:

  • 标准帧:11位ID,IDE=0(显性),仲裁优先级高
  • 扩展帧:29位ID,IDE=1(隐性),仲裁优先级低
  • 扩展帧多了SRR位(替代远程请求位),位于IDE之前

嗯,这里还要提一句:扩展帧的SRR位在标准帧的RTR位位置。SRR始终是隐性(1),所以如果标准帧和扩展帧同时发送,标准帧的RTR位如果是显性(数据帧),那标准帧赢。如果标准帧是远程帧(RTR=1),那两者都是隐性,继续比后面的IDE位。

4.2 BRS位:CAN FD的“变速杆”

BRS位,全称是Bit Rate Switch。说白了,它就是CAN FD的变速杆。你想想看,传统CAN最高只能到1Mbps,但CAN FD可以在数据段飙到8Mbps甚至更高。怎么做到的?就是靠这个BRS位。

BRS位位于控制场中。当BRS=1(隐性)时,表示从BRS位之后切换到高速率传输数据段。当BRS=0(显性)时,表示全程用标称速率(仲裁段速率)。

我个人习惯把BRS位看作一个开关。仲裁段大家慢慢来,保证谁都能抢到总线。数据段嘛,既然已经抢到了,那就赶紧把数据发完,越快越好。所以BRS=1是CAN FD的典型用法。

我的经验: 有些老旧的CAN FD控制器不支持BRS切换。如果你在混合网络中发送BRS=1的帧,老设备可能会报错。所以设计网络时,一定要确认所有节点都支持CAN FD的BRS功能。

4.3 ESI位:错误状态的“信号灯”

ESI位,Error State Indicator。这个位很有意思。它告诉接收方:发送节点当前处于什么错误状态。

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

为什么需要这个位?我举个例子。假设一个节点因为干扰频繁出错,进入了错误被动状态。按照CAN协议,错误被动节点发送完数据后,不能主动发送错误帧。但接收方不知道啊。有了ESI位,接收方一看:哦,这家伙是错误被动,我得小心点,可能它的数据不太靠谱。

我在项目中遇到过这样的情况:某个ECU频繁报错,但就是查不出原因。后来抓波形一看,ESI位一直是1。说明这个节点已经处于错误被动状态了。顺着这个线索,发现是它的CAN收发器供电不稳。你看,ESI位就是一个很好的诊断线索。

注意: ESI位只在CAN FD帧中有效。传统CAN帧没有这个位。另外,ESI位只在数据段中传输,仲裁段不包含ESI信息。

4.4 CRC计算:17位 vs 21位

CRC是CAN FD的重头戏。传统CAN用15位CRC,CAN FD根据数据长度不同,用17位或21位CRC。

具体规则是这样的:

  • 数据长度 ≤ 16字节:用17位CRC
  • 数据长度 > 16字节:用21位CRC

为什么这么分?说白了,数据越长,出错的概率越大,需要的CRC多项式阶数就越高。17位CRC的生成多项式是x¹⁷ + x¹⁶ + x¹⁴ + x⁴ + 1。21位的是x²¹ + x²⁰ + x¹³ + x¹¹ + x⁷ + x⁴ + x³ + 1。

你可能会问:那传统CAN的15位CRC还能用吗?答案是:不能。CAN FD的CRC覆盖范围更广,包括了填充位。嗯,这里要特别注意——传统CAN的CRC不包含填充位,但CAN FD的CRC包含了填充位。这是为了增强错误检测能力。

CRC计算范围:

  • 起始位(SOF)
  • 仲裁场(ID、RTR、IDE等)
  • 控制场(DLC、BRS、ESI等)
  • 数据场(所有数据字节)
  • 填充位(包括插入的填充位)

我建议你在实现CRC计算时,直接用硬件CRC模块。别自己写软件算,容易出错。有一次我手写了一个CRC校验函数,结果跟硬件算出来的对不上。查了半天,发现是填充位的处理顺序搞反了。从那以后,我再也不敢手动算CRC了。

4.5 填充位规则:0/1交替的“防呆”机制

填充位是CAN协议的一个经典设计。它的规则很简单:连续发送5个相同电平的位之后,必须插入一个相反电平的位。

比如你连续发了5个1,那第6位必须插入一个0。反过来,连续5个0,第6位插入一个1。这就是所谓的“0/1交替”。

为什么要这么做?因为CAN总线是靠电平变化来同步时钟的。如果长时间没有电平变化(比如连续10个1),接收方的时钟就会漂移,导致采样错误。填充位保证了总线上最多每5位就有一次电平跳变。

在CAN FD中,填充位的规则跟传统CAN一样。但要注意:CAN FD的数据段速率更高,填充位的插入和删除必须非常快。如果控制器处理不过来,就会出错。

避坑指南: 我曾经在一个项目中,把CAN FD的速率设到了8Mbps。结果发现某些节点的填充位处理有问题,导致CRC校验失败。后来把速率降到5Mbps就正常了。所以,不要盲目追求高速率,要确认控制器的处理能力。

另外,填充位会影响CRC计算。因为CRC计算时要把填充位也算进去。所以你在设计CRC硬件或软件时,一定要把填充位纳入计算范围。否则,发送方和接收方的CRC对不上。

4.6 帧结构完整示例

最后,我给你一个完整的CAN FD标准帧结构示例。假设数据长度为8字节,BRS=1,ESI=0:

SOF | 11位ID | IDE=0 | r0 | BRS=1 | ESI=0 | DLC=1000 | 数据(8字节) | CRC(17位) | CRC分隔符 | ACK | ACK分隔符 | EOF

注意:这里的r0是保留位,始终为显性(0)。DLC=1000表示8字节数据。CRC是17位的,因为数据长度≤16字节。

如果是扩展帧,结构会变成这样:

SOF | 11位ID | SRR=1 | IDE=1 | 18位扩展ID | r1 | r0 | BRS=1 | ESI=0 | DLC | 数据 | CRC | ...

嗯,这里r1也是保留位,始终为显性。扩展帧比标准帧多了SRR位和18位扩展ID,所以帧长度更长。

好了,这一章的内容就到这里。帧结构是CAN FD的基础,搞懂了这些位的作用,你就能看懂任何CAN FD波形了。下一章我们聊聊CAN FD的物理层设计,那又是另一番天地。