1、概述
本文只探讨Can在busoff方面的内容,基于Tc27x单片机,在日常项目里面,busoff属于频发的故障类型,时常在UDS诊断部分见到这个故障,很头疼,目前项目里面直接硬件检测到busoff就上报,检测到连续128次隐性电平直接就恢复了(这里个人理解对CAN来说就是128bit),恢复合理符合标准,但是直接上报这种是不合理的,但是架不住客户要求。
2、什么是busoff
CAN总线的Bus Off是指当CAN节点发送错误次数超过规定的限制时,该节点将被自动禁用。在这种情况下,节点将停止发送消息,并进入“Bus Off”状态,直到节点被重置或重新启动。这是一种保护机制,以避免错误消息在网络中传播并导致其他节点出现问题。
在CAN总线进入busoff状态后,通常需要尝试重新连接总线。这可以通过在CAN控制器中执行一系列的错误恢复步骤来实现,例如等待一段时间以允许其他节点发送消息,然后逐渐增加发送消息的速率,直到成功连接总线为止。如果这些尝试都失败了,那么可能需要重启CAN控制器。
3、故障判断
为了避免X某个设备因为自身原因(例如硬件损坏)导致无法正确收发报文而不断的破坏总线的数据帧,从而影响其它正常节点通信,CAN网络具有严格的错误诊断功能,CAN通用规范中规定每个CAN控制器中有一个发送错误计数器和一个接收错误计数器。根据计数值不同,节点会处于不同的错误状态,并根据计数值的变化进行状态转换,状态转换如下图所示。
注意一个点:节点发送失败,发送错误计数TEC 是加8的:TEC+8 节点发送成功减去1,TEC – 1,进入Busoff需要的是TEC>255,这样计算下来,也就是32次错误中断之后就会busoff。这32次怎么去产生呢?干扰连续的32帧发送数据即可。但是假设总线上只有一个CAN节点,没有其他节点产生应答,监控总线只会出现错误帧,错误帧类型NACK,不会进入busoff的,并不是出现错误帧就会进入busoff。
以上三种错误状态表示发生故障的严重程度,总线关闭是节点最严重的错误状态。并且,节点在不同的状态下具有不同的特性,在总线关闭状态下,节点不能发送报文或应答总线上的报文,也就意味着不能再对总线有任何影响。
状态跳转和错误计数的规则使得节点在发生通信故障时有了较好的自我错误处理和恢复机制,从一种较严重的错误状态跳转到另一种严重性相对较低的状态,本质上就是一种恢复过程。上图所呈现的转换过程是CAN通用规范所要求的,我们从设备供应商买回来的CAN控制器已经把这些功能固化在MCU之中了。
在通信过程中,错误主动和错误被动两种状态下节点的恢复过程一般不需要MCU进行额外的编程处理,直接使用CAN控制器固有功能即可。但对于总线关闭状态,往往不直接使用CAN控制器固有的恢复过程,而是对其进行编程控制,以实现“快恢复”和“慢恢复”机制。
当节点进入总线关闭状态后,如果MCU仅是开启自动恢复功能,CAN控制器在检测到128次11个连续的隐性位后即可恢复通信,在实际的CAN通信总线中,这一条件是很容易达到的。以250K的波特率为例,128*(1/250000)*11= 5.632ms。这意味着如果节点所在的CAN总线的帧间隔时间大于5.632ms s,节点在总线空闲时间内便可轻易恢复通信。我们已经知道,当进入总线关闭状态时,节点已经发生了严重的错误,处于不可信状态,如果迅速恢复参与总线通信,具有较高的风险,因此,在实际的应用中,往往会通过MCU对CAN控制器总线关闭状态的恢复过程进行编程处理,以控制节点从总线关闭状态恢复到错误主动状态的等待时间,达到既提高灵活性又保证节点在功能上的快速响应性的目的。具体包括“快恢复”和“慢恢复”策略,两种策略一般同时应用。
4、恢复策略
(1)MCU仅开启CAN控制器的自动恢复功能,节点只需检测到128次11个连续的隐性位便可以恢复通信,恢复过程如下图所示。
(2)MCU没有开启CAN控制器(寄存器方面)的自动恢复功能,也不主动干预总线关闭错误,节点将一直无法“自动”恢复总线通信,只能通过重新上电的方式使节点恢复, 恢复过程如下图所示。
(3)MCU对CAN控制器的恢复过程进行编程处理,这时,节点的恢复行为由具体的编程逻辑决定,各厂家普遍采用了先“快恢复”后“慢恢复”的恢复策略,恢复过程如下图所示。
5、快慢恢复机制
先简单的看下里面的三个概念
快恢复
Busoff发生后,先进行CanSMBorCounterL1ToL2次(例如5次)时间间隔为CanSMBorTimeL1(例如100ms)的快恢复。
慢恢复
在进行CanSMBorCounterL1ToL2次尝试恢复后,如果仍然发生busoff,转为慢恢复,时间间隔为CanSMBorTimeL2(例如2000ms)。进入慢恢复后一直执行慢恢复。
恢复成功
每次尝试busoff恢复时,CanSM会重新启动CAN控制器发送,启动后如果在CanSMBorTimeTxEnsured(例如40ms)时间内不再发生busoff,则认为busoff恢复成功。
节点以正常发送模式发送报文的过程中,如果出现了发送错误,发送错误计数会增加,只要发送错误计数没有超过255, CAN控制器便会自动重发报文,如果出现多次发送错误,使发送错误计数累加超过255,则节点跳转为总线关闭状态。MCU能够第一时间知道节点进入了总线关闭状态(例如在错误中断处理逻辑中查询状态寄存器的相应位,下文会介绍寄存器),这时MCU控制CAN控制器进入“快恢复”过程,即控制CAN控制器停止报文收发,并进行等待,计时达到需要的时间T1(如100ms)后,MCU重新启动恢复CAN控制器参与总线通信,这样便完成了一次“快恢复”过程。
注意一下:进入快恢复的前提是硬件已经检测到busoff了。
节点每进入一次“快恢复”过程时,MCU会对此进行计数,当节点“快恢复”计数达到设定的值N(如5次),则后续再次进入总线关闭状态时MCU把恢复总线通信的等待时间T2进行延长(如2000ms),这样便实现了“慢恢复”过程。“快恢复”和“慢恢复”过程的主要区别就在于恢复节点参与总线通信的等待时间的不同。
通过MCU对于总线关闭后的恢复行为进行编程控制,实际上是对CAN控制器的错误管理和恢复机制进行了补充,使得总线关闭状态后的恢复过程更加灵活,更能适应实际应用的需要。对于 “快恢复”和“慢恢复”的等待时间,以及“快恢复”计数多少次后进入“慢恢复”过程,不同厂家可根据具体的需求进行编程实现。
6、AUTOSAR恢复程序设定
(1) CAN control产生中断,在中断查询是否出现BUSOFF。
(2) 若产生BUSOFF则CANSM 重启CAN controller,并将ComM置为(Silent)、BswM置为(BUSOFF),打开Rx PDU 关闭Tx PDU;同时会启动一个BUSOFF timer。
(3)当BUSOFF timer 时间耗尽,则会打开Tx PDU,并将ComM置为(FULL)、BswM置为(FULL),同时启动 TxEnsureTimer 确定BUSOFF 是否确实回复。
(4)若TxEnsureTimer 耗尽之前再一次出现BUSOFF,则开始下一次的BUSOFF 恢复机制。
CAN State Manager要做什么?
The CanSm module is responsible for mode control management of all supported CAN Controllers and CAN Transceivers.
该模块需要实现为每一个CAN控制器实现CAN Bus Off恢复算法[SRS_Can_01146]
该模块需要支持CAN Bus Off恢复时间配置[SRS_Can_01143]
该模块需要提供一个接口,以在上电初始化时,支持通信模式配置(No communication,or silent communication)[SRS_Can_01144]
CanSM_BSM
在状态CANSM_BSM_S_FULLCOM下需要进行Bus Off事件的处理,意味着在CAN通信处于全通信(发送,接收功能正常)状态下,发生Bus Off事件,需要进行Bus Off
在状态CANSM_BSM_S_SILENTCOM下,需要处理Bus Off事件。一开始看到这个状态下需要发生Bus Off事件会有些不解,这个状态下怎么会发生Bus Off事件呢?Bus off事件不是在发送报文计数器TEC>255的条件下,才会发生吗?CANSM_BSM_S_SILENTCOM这个模式,不是代表静默模式吗,不就是只接收,不发送吗?不发送CAN报文,怎么会发送TEC > 255的情况呢?
这个场景可能在临界的情况下发生,也就是CAN State Manager请求进入CANSM_BSM_S_SILENTCOM状态后,下层CAN controller外设还在发送CAN报文,发送不能成功,也就可能发生了Bus Off的事件。
7、实际测试
错误寄存器
busoff寄存器
实验里面有两个Can节点在同一个总线上,短接CANH与CANL之后出现如下。
寄存器bit位一直在变化,因为我这边设置的,立即恢复,没有快慢恢复,所以比较难抓取。