3、CANFD数据链路层:帧结构详解
各位工程师朋友,咱们今天来聊聊CANFD的数据链路层。说实话,这一层是CANFD通信的核心,搞懂了它,你调试总线时心里就有底了。我个人习惯把数据链路层比作「快递包裹」——每个帧就是一个包裹,里面装着你要送的数据,外面贴着各种标签和校验码。
CANFD的帧结构,说白了就是一套严格的格式规范。它由七个部分组成:SOF、仲裁场、控制场、数据场、CRC场、ACK场和EOF。咱们一个一个来看。
3.1 SOF(帧起始)
SOF就是一个显性位(逻辑0),告诉总线上所有节点:「注意,我要开始发数据了!」。嗯,这里要注意,SOF是同步的基础,所有节点的时钟都靠它来对齐。我在项目中遇到过,有些新手设计的节点在SOF之后采样点没对准,结果整个帧都读错了——这种问题排查起来特别头疼。
3.2 仲裁场
仲裁场包含ID和RTR位。CANFD的ID可以是11位(标准帧)或29位(扩展帧)。你想想看,为什么要有仲裁?因为多个节点可能同时发数据,总线需要决定谁优先。ID越小,优先级越高。
这里有个关键点:CANFD的仲裁场和CAN2.0完全兼容。也就是说,CANFD节点和CAN2.0节点可以在同一总线上共存,但仲裁逻辑不变。我曾经调试过一个混合网络,CANFD节点和CAN2.0节点抢总线,结果CANFD节点因为ID设得太高,老是发不出去——后来我把ID改小了,问题就解决了。
避坑指南:我曾经见过有人把CANFD的ID设成0x7FF(标准帧最高ID),结果这个节点几乎永远抢不到总线。记住,ID越小,优先级越高。如果你想让某个节点优先发送,给它分配一个较小的ID。
3.3 控制场
控制场包含IDE位、FDF位、BRS位、ESI位和DLC。咱们重点说几个。
IDE位:标识是标准帧还是扩展帧。IDE=0表示标准帧,IDE=1表示扩展帧。
FDF位:这是CANFD和CAN2.0的关键区别。FDF=0表示这是CAN2.0帧,FDF=1表示这是CANFD帧。说白了,接收节点看到FDF=1,就知道要用CANFD的规则来解析后面的内容。
BRS位:位速率切换标志。BRS=1表示从BRS位之后切换到高速率传输(数据段用更快的速率)。BRS=0表示全程用仲裁段的速率。我个人习惯在数据量大的时候把BRS置1,这样能大幅提升吞吐量。
ESI位:错误状态指示。ESI=0表示发送节点处于主动错误状态,ESI=1表示处于被动错误状态。嗯,这个位在故障诊断时很有用。
3.4 数据场长度编码(DLC)
DLC是数据场长度编码,它告诉接收方数据场有多少个字节。CAN2.0的DLC只能表示0-8字节,但CANFD扩展了DLC的编码范围,最大可以到64字节。
具体编码规则如下:
| DLC值 | CAN2.0数据长度(字节) | CANFD数据长度(字节) |
|---|---|---|
| 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 |
你想想看,为什么CANFD要支持64字节?因为现在车载网络的数据量越来越大,比如OTA升级、高精度地图传输,8字节根本不够用。我记得有一次帮客户调试一个ADAS系统,他们用CAN2.0传摄像头数据,一个目标信息要拆成好几个帧,延迟大得离谱。后来换成CANFD,一帧搞定,延迟直接降了一个数量级。
个人经验:DLC值9-15在CAN2.0中虽然也能编码,但数据长度仍然是8字节。如果你在CAN2.0网络中收到DLC=15的帧,别以为它有64字节数据——它只有8字节。这个坑我踩过,当时查了半天,最后发现是DLC解析错了。
3.5 数据场
数据场就是实际传输的数据,长度由DLC决定。CANFD的数据场可以是0-64字节。嗯,这里要注意,数据场的字节顺序是MSB优先(大端模式),但有些控制器支持配置字节序。我个人习惯统一用大端,避免跨平台时出问题。
3.6 CRC场
CRC场包含CRC序列和CRC分隔符。CANFD的CRC算法和CAN2.0不同,它支持17位或21位CRC,具体取决于数据长度。数据长度≤16字节时用17位CRC,>16字节时用21位CRC。
为什么CRC要分两种?说白了,数据越长,CRC的检错能力要求越高。21位CRC的汉明距离更大,能检测出更多错误。我在项目中遇到过,有个节点因为CRC计算错误,导致整个网络频繁重传——后来发现是CRC多项式配置错了,CANFD和CAN2.0的CRC多项式不一样。
警告:CANFD的CRC计算范围包括SOF、仲裁场、控制场、数据场,但不包括CRC场本身和ACK场。有些初学者以为CRC只校验数据场,结果CRC校验总是不通过——嗯,这个错误我见过不下五次。
3.7 ACK场
ACK场包含ACK槽和ACK分隔符。发送节点在ACK槽发送隐性位(逻辑1),接收节点如果正确接收到帧,就在ACK槽发送显性位(逻辑0)来确认。说白了,这就是一个「我收到了」的握手信号。
如果没有任何节点发送显性位,发送节点就知道这个帧没有被正确接收,然后会重发。我曾经调试过一个总线,发现某个节点总是收不到ACK——后来发现是它的收发器坏了,无法驱动总线。换了个收发器,问题就解决了。
3.8 EOF(帧结束)
EOF是7个隐性位,表示帧的结束。嗯,这里要注意,EOF之后还有ITM(帧间空间),至少需要3个隐性位。如果你在EOF之后立即发送下一帧,总线会报错。
3.9 位速率切换(BRS)标志详解
BRS标志是CANFD最核心的特性之一。它允许在同一个帧内切换速率:仲裁段用标准速率(比如500kbps),数据段用高速率(比如2Mbps甚至更高)。
为什么需要切换速率?你想想看,仲裁段需要所有节点同步,速率不能太高,否则信号传播延迟会导致仲裁失败。但数据段不需要仲裁,可以跑得更快。BRS标志就是用来告诉接收节点:「注意,我要加速了!」
BRS位的具体位置在控制场的FDF位之后。当BRS=1时,从BRS位之后的采样点开始切换到高速率,直到CRC场的CRC分隔符之前切换回标准速率。
关键点:BRS切换不是瞬间完成的,它需要一定的同步时间。我个人建议,高速率不要超过仲裁速率的8倍,否则信号质量会下降。比如仲裁速率500kbps,数据速率最高4Mbps。我曾经试过5Mbps,结果误码率飙升——嗯,这个教训很深刻。
另外,BRS标志只在CANFD帧中有效。如果你在CAN2.0帧中看到BRS位,那它其实是保留位,必须为显性(0)。有些控制器如果收到BRS=1的CAN2.0帧,会直接报错。这个兼容性问题,我在混合网络中遇到过好几次。
好了,帧结构就讲到这里。下一章咱们聊聊CANFD的物理层,看看信号是怎么在总线上传输的。记住,帧结构是基础,搞懂了它,你就能读懂总线上的每一比特数据。