CAN FD 数据链路层:帧结构、仲裁与位填充

我记得刚接触 CAN FD 那会儿,总觉得数据链路层就是个协议栈,调调参数就行。直到有一次,EMI 干扰把总线打得七零八落,我才发现——不懂链路层细节,你连错误帧长什么样都看不懂。

这一节,我们就把 CAN FD 的帧结构、仲裁机制和位填充掰开揉碎。说白了,这三样东西决定了数据怎么装车、怎么抢道、怎么防干扰。

3.1 CAN FD 帧结构:标准帧 vs 扩展帧

CAN FD 的帧结构和传统 CAN 2.0 很像,但多了几个关键字段。我习惯把帧想象成快递包裹——有头、有身子、有尾巴。

先看帧头:

  • SOF(Start of Frame):一个显性位,告诉所有节点“我要发数据了”。
  • 仲裁场(Arbitration Field):包括 ID 和 RTR 位。标准帧 11 位 ID,扩展帧 29 位 ID。
  • 控制场(Control Field):CAN FD 这里加了 FDF、BRS、ESI 位,用来标识是 FD 帧还是传统帧。

再看数据场:最多 64 字节,比传统 CAN 的 8 字节翻了 8 倍。

帧尾:CRC 校验、ACK 位、EOF。这里有个坑——CAN FD 的 CRC 比传统 CAN 多,特别是数据场超过 16 字节时,CRC 要用 21 位甚至更多。

字段 标准 CAN (2.0) CAN FD
仲裁场 ID 11 位 11 或 29 位
控制场 IDE, r0, DLC FDF, BRS, ESI, DLC
数据场长度 0~8 字节 0~64 字节
CRC 15 位 17 或 21 位
位速率切换 不支持 支持,数据场可高速
实战提醒:我在项目里常用标准 11 位 ID,除非节点特别多。扩展帧虽然 ID 多,但仲裁阶段多了 18 位,EMI 干扰更容易弄丢位。你想想看,总线要是被干扰,这 18 位哪个错了,仲裁就崩了。

3.2 仲裁机制:谁先抢到总线?

仲裁,说白了就是多个节点同时发数据时,谁能赢。

CAN 总线的物理层用了“线与”逻辑:显性位(逻辑 0)会覆盖隐性位(逻辑 1)。所以,ID 数值越小,优先级越高。

举个例子:节点 A 的 ID 是 0x100,节点 B 是 0x200。两者同时开始发送:

  1. A 发 ID 位 0x100 的二进制:0001 0000 0000
  2. B 发 ID 位 0x200 的二进制:0010 0000 0000
  3. 第一位:A 发 0(显性),B 也发 0(显性)。两者都不让步。
  4. 第二位:A 发 0(显性),B 发 1(隐性)。显性盖过隐性,A 赢。

为什么会这样?因为 B 在第二位看到总线不是自己发的东西,就知道有人优先级更高,它立刻停止发送,转为接收。

这个机制在 EMI 下会出问题。我曾经遇到过:总线被干扰,一个节点本来该发隐性位,结果收到了显性电平,误以为在仲裁中输了——于是它停止发送,后面一帧全乱。这就是典型的错误帧来源之一。

关键结论:仲裁失败不是错误帧,但仲裁阶段受 EMI 干扰,会虚假触发错误帧。调试时优先看 SOF 之后的几个位,有没有不该出现的显性电平。

3.3 位填充:同步与错误检测的基石

位填充,名字听着吓人,其实很简单:发送方每发送 5 个连续相同电平的位,就插入一个相反电平的位。

比如你发连续 5 个隐性位(11111),填充规则会自动加一个显性位(0)。接收方看到这 6 个位,知道第 6 个是填充位,不把它当数据。

为什么搞这么复杂?两个原因:

  • 同步:CAN 节点没有独立的时钟线,靠总线电平跳变同步时钟。连续相同电平超过 5 位,时钟可能漂移,节点之间不同步了。
  • 错误检测:如果接收方看到连续 6 个相同电平,就知道这是违规的——填充规则要求最多 5 个连续相同位。这就是“填充错误”。

嗯,这里要注意:位填充规则适用于从 SOF 到 CRC 场(包括 CRC 本身)。ACK 场、EOF、帧间隔等不填充。

// 举例:发送数据 0xFF(二进制 1111 1111)
// 按位填充规则:
// 原始:1 1 1 1 1 1 1 1
// 填充后:1 1 1 1 1 0 1 1 1 1 1 0 ...
// 你看,每5个1插入一个0,打破了连续相同电平

在我以前的项目中,遇到过别车厂反馈——EMI 干扰导致插入的填充位被误判成数据位,CRC 校验收到的帧就不对,最终触发错误帧。解决办法是检查总线终端电阻和共模扼流圈,填充位错误率大幅下降。

避坑指南:我曾经在实验室用信号发生器给 CAN FD 总线注入干扰,结果填充位错误反复出现。查了半天,发现是节点晶振误差超过 0.5%。CAN FD 数据场速率一高,同步窗口缩小,填充位就扛不住了。确保所有节点晶振精度在 ±0.3% 以内。

3.4 本章知识结构图

下面这张图把 CAN FD 数据链路层的核心逻辑串起来了——从帧结构到仲裁,到位填充,再到错误帧触发。你可以把它当成调试时的思维地图。

CAN FD 数据链路层核心逻辑 帧结构 标准帧 11位ID / 8字节数据 15位CRC 扩展帧 29位ID / 64字节数据 21位CRC FD特有字段 FDF / BRS / ESI 位速率切换 仲裁机制 非破坏性仲裁 显性位覆盖隐性位 ID数值越小优先级越高 EMI干扰影响 隐性位被误判为显性 虚假仲裁失败 → 错误帧 位填充 最多连续5个相同位 第6位强制插入相反位 作用:同步 + 错误检测 连续6个相同位 = 填充错误 错误帧 触发逻辑 仲裁或 填充错误

图里你能看到三个模块怎么串起来的。帧结构决定了数据封装方式;仲裁机制决定总线控制权;位填充保证同步和错误检测。任何一个环节受 EMI 干扰,最终都可能表现为错误帧。

好了,这就是 CAN FD 数据链路层的核心。下面我们看实战中怎么抓这些信号、怎么分析错误帧。