3. CAN仲裁机制:CSMA/CR原理、ID优先级仲裁、非破坏性逐位仲裁过程
好,咱们今天聊CAN总线里最精彩的部分——仲裁机制。
说实话,我刚入行那会儿,总觉得CAN的仲裁挺玄乎的。多个节点同时发数据,怎么就能不冲突呢?以太网那边还在搞CSMA/CD,碰撞了还得重传,CAN倒好,直接“无损”搞定。这里面的门道,我今天给你掰开揉碎了讲。
3.1 CSMA/CR:不是CD,是CR
先看这个缩写。CSMA大家都熟——载波监听多路访问。但关键是后半截:
- 以太网用的是CSMA/CD(Collision Detection,碰撞检测)。发现冲突了,停!等随机时间再重发。
- CAN总线用的是CSMA/CR(Collision Resolution,碰撞解决)。发现冲突了,不慌,咱们按规矩来,谁优先级高谁继续发。
一字之差,天壤之别。CD是事后补救,CR是当场解决。
核心思想:多个节点同时发送时,通过ID的“显性位”覆盖“隐性位”,实现无损仲裁。胜出的节点继续发,失败的节点自动转为接收,不丢数据,不浪费带宽。
我当年调试一个多节点系统时,遇到过一个问题:总线利用率一高,某些低优先级报文就发不出去。后来一查,就是仲裁机制在“公平性”上的天然缺陷。这个后面细说。
3.2 ID优先级仲裁:数字越小,权力越大
CAN的仲裁,说白了就是比ID大小。但注意,是二进制数值越小,优先级越高。
为什么?因为显性位(逻辑0)能覆盖隐性位(逻辑1)。
咱们看个例子。假设两个节点同时发送:
- 节点A:ID = 0x7E0(二进制:111 1110 0000)
- 节点B:ID = 0x7E8(二进制:111 1110 1000)
从最高位开始逐位比较:
| 位序 | 节点A | 节点B | 总线状态 | 说明 |
|---|---|---|---|---|
| 1 | 1 | 1 | 1 | 相同,继续 |
| 2 | 1 | 1 | 1 | 相同,继续 |
| ... | ... | ... | ... | ... |
| 8 | 0 | 1 | 0 | 节点A胜出! |
看到了吗?在第8位,节点A发送显性位0,节点B发送隐性位1。总线被拉低为0,节点B发现自己发送的是1但总线是0,就知道自己输了,立刻停止发送,转为接收。
我的经验:设计ID分配时,一定要把最紧急的报文(比如刹车、安全气囊)分配最小的ID。我见过有人把诊断报文设成0x001,结果一跑诊断,正常控制报文全被堵死了。嗯,这种坑踩过一次就记住了。
3.3 非破坏性逐位仲裁过程
“非破坏性”这三个字,是CAN仲裁的精髓。什么意思?就是仲裁过程中,胜出的节点继续发它的完整报文,不需要重传。失败的节点只是停止发送,但已经发出去的数据不会损坏。
咱们把整个过程拆解一下:
- 总线空闲:所有节点监听总线,发现连续11个隐性位,知道总线空闲了。
- 同步发送:多个节点同时开始发送SOF(帧起始,显性位)。
- 逐位仲裁:从ID的最高位开始,每个节点发送一位,同时读取总线状态。
- 胜负判定:如果自己发送的位与总线状态一致,继续;如果不一致,说明输了,立即停止发送。
- 胜者继续:胜出的节点不受影响,继续发送剩余的数据帧。
- 败者重试:失败的节点在总线再次空闲时,自动重发刚才的报文。
整个过程,发生在几个微秒之内。你想想看,硬件级别的仲裁,比软件快多了。
注意:仲裁只在ID段进行。一旦进入控制段和数据段,就不再仲裁了。所以ID的分配直接决定了报文的实时性。
3.4 扩展帧与标准帧的仲裁
CAN有标准帧(11位ID)和扩展帧(29位ID)。它们能共存吗?能。但仲裁规则有点特殊:
- 标准帧的IDE位是显性(0)
- 扩展帧的IDE位是隐性(1)
所以,如果标准帧和扩展帧同时发送,标准帧一定赢。因为IDE位在SRR位之后,标准帧的IDE是显性,扩展帧的IDE是隐性。
我记得有一次,客户抱怨说他们的扩展帧报文老是发不出去。我一查,总线上有个标准帧的ID设成了0x000,优先级最高,而且频率特别高。扩展帧根本抢不过。最后只能把那个标准帧的ID调大,或者降低发送频率。
3.5 仲裁的物理层基础
仲裁能实现,离不开CAN的物理层设计:
- 显性位:CAN_H高,CAN_L低,差分电压约2V
- 隐性位:CAN_H和CAN_L都是2.5V,差分电压0V
显性位能“覆盖”隐性位,是因为总线采用“线与”逻辑。只要有一个节点拉低总线,总线就是低电平。
说白了,这就是个“谁更强势谁说了算”的机制。
3.6 避坑指南:我踩过的几个坑
做CAN开发这么多年,仲裁相关的坑真不少。分享几个:
- 坑一:ID分配不合理。我曾经把两个ECU的ID设反了,结果高优先级的报文被低优先级的堵死。查了两天才发现。
- 坑二:忽略仲裁场长度。标准帧仲裁场12位,扩展帧32位。仲裁时间不一样,会影响总线时序。
- 坑三:误以为仲裁是公平的。CAN仲裁不是轮询,低优先级报文可能永远发不出去。设计时一定要考虑最坏情况。
建议:做系统设计时,先画一张ID分配表。把报文按紧急程度排序,紧急的给小编号。然后算一下最坏情况下的总线负载,确保低优先级报文也能在规定时间内发出去。
3.7 知识体系图
下面这张图,把CAN仲裁的核心逻辑串起来了。我建议你多看几遍,理解透。
这张图把CAN仲裁的三个核心维度串起来了。从上到下,先理解CSMA/CR的宏观思想,再深入到ID仲裁、逐位过程和物理层支撑。我建议你把这个图打印出来,贴在工位上。
公众号:蓝海资料掘金营,微信deep3321