3、CAN FD 帧格式:数据帧、远程帧、错误帧、过载帧的结构
咱们做 CAN FD 开发,天天跟帧打交道。四种帧类型——数据帧、远程帧、错误帧、过载帧,就像交通灯的红黄绿,各有各的活儿。我个人习惯先把它们放一块儿对比一下,再看细节。
| 帧类型 | 作用 | 是否带数据 | 典型场景 |
|---|---|---|---|
| 数据帧 | 发送节点把数据丢到总线上 | 是(0~64 字节) | 传感器周期上报、ECU 间通信 |
| 远程帧 | 请求某个 ID 的数据帧 | 否(无数据场) | 主机轮询从节点数据 |
| 错误帧 | 通知总线发生了错误 | 否(只含错误标志) | CRC 错、位填充错等 |
| 过载帧 | 接收节点忙,请求延迟下一帧 | 否(只含过载标志) | 接收缓冲区满 |
嗯,先记住这个表。下面我挨个掰开讲讲。
3.1 数据帧——最常用的那个
数据帧分两类:标准帧(11 位 ID)和 扩展帧(29 位 ID)。CAN FD 还多了一个标志:BRS(位速率切换)和 ESI(错误状态指示)。结构上分为七个场:
- 帧起始(SOF):1 位显性,同步用。
- 仲裁场:标准帧 12 位(11 位 ID + RTR),扩展帧 32 位(11 位基本 ID + SRR + IDE + 18 位扩展 ID)。注意这里的 RTR 在数据帧里是显性(0),远程帧里是隐性(1),CAN FD 里 RTR 必须为显性。
- 控制场:标准帧 6 位(IDE + r0 + DLC),CAN FD 里变成 8 位(IDE + r0 + BRS + ESI + DLC)。BRS 为 1 时切换到高速率。
- 数据场:0~64 字节,跟传统 CAN 最大 8 字节大不一样。
- CRC 场:CAN FD 的 CRC 长度根据数据字节数动态变化(17 位或 21 位),包含填充位计数器。
- ACK 场:2 位(ACK 槽 + 分隔符),接收节点拉显性表示确认。
- 帧结束(EOF):7 位隐性。
我之前遇到过一个坑:BRS 位如果在发送端设了 1,但接收端不支持 CAN FD,那就会触发错误帧。所以用 CAN FD 之前,一定得确认总线上所有节点都支持协议。
3.2 远程帧——只请求,不带数据
远程帧的结构跟数据帧几乎一样,唯一的区别是 仲裁场的 RTR 位为隐性(1),而且数据场长度为 0。CAN FD 标准里仍然保留了远程帧,但 BRS 和 ESI 的含义跟数据帧相同。你想想看,远程帧本质上就是个“找你要数据”的信号。
我建议在工程应用里少用远程帧,因为多节点同时发送远程帧容易导致仲裁丢失,不如用专用数据帧做周期性轮询。当然,传统 CAN 协议里远程帧用得挺多,咱们做兼容设计时还是得支持。
3.3 错误帧——总线的自我修复机制
错误帧由两部分组成:
- 错误标志:6 个连续显性位(主动错误)或 6 个连续隐性位(被动错误)。
- 错误界定符:8 个隐性位。
说白了,任何一个节点检测到错误(比如 CRC 不匹配、位填充错、ACK 错),就会立刻打断当前帧,拉 6 个显性位。其他节点收到这 6 个显性位后,也会跟着发错误标志——这样就在总线上形成了 6~12 个显性位。注意,如果发送节点是“错误被动”状态,它只能发 6 个隐性位,这时候不会干扰正常通信。
我记得在实验室里调一个 CAN FD 节点,总线上一直出现错误帧。后来抓出来是时钟精度不够,导致位时序采样点偏差。嗯,这玩意儿用示波器看波形才揪出来。
3.4 过载帧——忙不过来的时候用
过载帧跟错误帧结构很像:
- 过载标志:6 个显性位。
- 过载界定符:8 个隐性位。
区别在于触发条件:过载帧是接收节点主动发的(比如接收缓冲区满了、帧间间隔过短)。注意,CAN FD 协议里过载帧的使用场景非常少,大部分控制器硬件会自动处理缓冲区压力。我建议在软件层面尽量预留足够的接收 FIFO 深度,别让过载帧在高速总线上出现,否则会拉低整体性能。
3.5 帧间空间——帧与帧之间的“间隔”
任何两帧之间必须有一段 帧间空间(Interframe Space),包括 3 位隐性位(IFS)。如果发送节点处于“错误被动”状态,中间还要多插 8 位隐性挂起传输位。这个细节很多人会忽略。我曾经在写上位机模拟器时,IFS 只给了 2 位,结果总线上总是出现莫名其妙的过载帧,查了半天才发现是 IFS 长度不满足规范。
busmaster 或 PCAN-View 配合 DBC 文件,把每个场的位级数据拉出来看。尤其是 CRC 场,CAN FD 的 CRC 算法跟传统 CAN 不一样,用逻辑分析仪抓波形对比最准。
好了,关于四种帧的结构就聊到这儿。记住一句话:搞懂数据帧的场结构,其他三种帧都是它的变体。后面章节我们还会深入解析仲裁机制和位填充,到时候你会有更深的理解。