4. CAN总线错误处理:错误类型、错误状态机、错误计数规则

CAN总线的错误处理机制,说实话,是它能在工业、汽车领域活这么久的核心原因之一。别的总线出错了可能就挂了,CAN不一样——它自己能发现错误、通知别人、还能自动恢复。我最早接触CAN的时候,觉得这东西挺“智能”的,后来深入一看,其实背后就是一套严谨的计数器和状态机在干活。

4.1 错误类型:CAN总线会出哪些问题?

CAN协议把错误分成了5类。你想想看,一个报文在总线上跑,从发送到接收,每个环节都可能出岔子。这5类错误基本覆盖了所有场景。

错误类型 检测位置 触发条件
位错误(Bit Error) 发送节点 发送的位与回读的位不一致(仲裁场和应答场除外)
填充错误(Stuff Error) 所有节点 连续6个相同电平出现,违反位填充规则
CRC错误(CRC Error) 接收节点 计算出的CRC与发送的CRC不匹配
格式错误(Form Error) 所有节点 固定格式位(如CRC界定符、ACK界定符)出现非法电平
应答错误(ACK Error) 发送节点 发送节点在ACK槽未检测到显性位(无人应答)

这里有个细节我提一下。位错误只有发送节点自己能检测到,因为它是在“发完一位后立刻回读”。而填充错误和格式错误,总线上的所有节点都能发现。我在项目里遇到过一种情况:某个节点因为晶振偏差太大,发出来的位宽不对,导致其他节点频繁报填充错误——其实发送节点自己还觉得挺正常的。

4.2 错误状态机:节点是怎么“变坏”的?

每个CAN控制器内部都维护着一个状态机。说白了,就是根据你犯错的次数,给你贴个标签。状态一共三个:错误主动、错误被动、总线关闭。

核心逻辑:错误计数越高,节点在总线上的“发言权”就越低。这是为了保护整个网络不被一个坏节点拖垮。

CAN节点错误状态机 错误主动 TEC<127 且 REC<127 错误被动 TEC>127 或 REC>127 总线关闭 TEC > 255 TEC/REC 超限 TEC/REC 降到127以下 TEC > 255 128个隐性位 + 复位 状态说明 • 主动:正常参与通信 • 被动:只能发被动错误帧 • 关闭:完全脱离总线

这个状态机怎么理解?我打个比方。你刚开始工作,偶尔犯错,领导觉得你态度好,这是“错误主动”。犯错多了,领导开始怀疑你能力,你说话也没人听了,这是“错误被动”。再犯大错,直接开除,这就是“总线关闭”。

4.3 错误计数规则:两个计数器怎么算?

每个CAN节点有两个计数器:发送错误计数器(TEC)和接收错误计数器(REC)。它们不是随便加减的,协议里有明确的规则。

我的经验:调试CAN总线问题时,我第一件事就是读这两个计数器的值。它们能告诉你,到底是哪个节点在“搞事情”。

4.3.1 发送错误计数(TEC)规则

  • 发送成功:TEC减1(前提是TEC > 0)
  • 发送错误:TEC加8
  • 发送时检测到位错误:TEC加8
  • 发送时ACK错误:TEC加8

4.3.2 接收错误计数(REC)规则

  • 接收成功:REC减1(前提是REC > 0)
  • 接收错误:REC加1
  • 接收时检测到CRC错误:REC加1
  • 接收时检测到填充错误:REC加1

注意:发送节点在发送过程中如果检测到填充错误或格式错误,TEC也是加8,不是加1。这个“8”和“1”的差距,就是为了让发送节点更快地进入错误被动状态,从而减少对总线的干扰。

4.4 错误帧:节点怎么告诉别人“我出错了”?

当一个节点检测到错误时,它会立刻发送一个错误帧。错误帧由两部分组成:错误标志和错误界定符。

节点状态 错误标志 说明
错误主动 6个显性位 主动告诉所有人“出错了”,会破坏当前报文
错误被动 6个隐性位 只能“小声”说,不破坏总线上的其他报文

这里有个有意思的点。错误主动节点发6个显性位,这违反了位填充规则,所以其他节点也会检测到填充错误,然后跟着发错误帧。结果就是,总线上会出现一堆重叠的错误标志,看起来像是一连串的显性位。我刚开始看波形的时候,还以为总线被拉死了,后来才知道这是“错误标志叠加”现象。

4.5 实战中的避坑指南

做CAN总线测试这么多年,有些坑我踩过,有些坑我看别人踩过。这里列几个常见的。

避坑1:我曾经遇到过一个问题,某个节点总是莫名其妙进入总线关闭状态。查了半天,发现是它的CAN收发器供电不稳,导致发送时偶尔输出电平不够,被自己检测到位错误。TEC一路飙升到255,直接关闭了。

避坑2:总线关闭后,节点需要检测到128个连续的隐性位才能恢复。但有些控制器要求软件手动复位才能退出总线关闭状态。我建议你在设计阶段就确认清楚芯片的行为,否则现场恢复会很麻烦。

避坑3:错误被动状态下,节点发送的被动错误帧是6个隐性位。隐性位很容易被总线上的显性位覆盖。这意味着,如果总线上有其他节点在发数据,这个错误帧可能根本没人注意到。所以,错误被动的节点其实很“憋屈”。

4.6 小结:错误处理的核心逻辑

CAN总线的错误处理,说白了就是一套“犯错-记分-惩罚”的机制。错误类型帮你定位问题,错误计数帮你量化严重程度,错误状态机帮你决定怎么处理。这三者配合起来,让CAN总线在恶劣的电磁环境下依然能稳定工作。

我个人习惯在测试时,用CAN分析仪同时监控TEC和REC的变化。如果某个节点的TEC在短时间内快速增加,那基本可以断定是这个节点在“捣乱”。反过来,如果REC增加很快,那可能是总线上的其他节点发的东西有问题,这个节点只是“受害者”。

嗯,错误处理这块内容就讲到这里。记住一句话:CAN总线不怕出错,怕的是出错了没人管。而错误处理机制,就是那个“管”的人。