1、测试中,为什么是32个错误帧出现一次Busoff?
Busoff的产生是因为TEC(Transmit Error Counter)>255导致,再次提醒:与REC(Receive Error Counter)无关。也就是说,如果节点状态切换到Busoff,是因为节点自身外发报文错误导致TEC>255。
回顾一下节点状态机,节点状态机如下所示:
在切入主题之前,对Error Passive状态做一个展开,节点由Error Active进入Error Passive,是因为REC>127 or TEC>127。所以,节点进入Error Passive状态的可以分两个层面看:
第一、总线上其他节点(eg:Node A)引发的错误,导致接收节点(eg:Node B)的REC>127。既然是外因,即:Node A错误导致Node B进入Error Passive状态,对Node B的最大"伤害"到此状态即可,Node B的通信状态没有什么问题,无需断开总线连接;
第二、发送节点引发错误,当TEC>127时,进入Error Passive状态,如果发送节点依然识别到自身发送报文有问题(有错误帧),为了降低对总线上其他节点的影响,发送节点要为自己的错误行为负责,当TEC>255时,节点需要暂时退出总线通信,之后尝试恢复通信。
对于节点的Error Passive和Busoff状态,驱动层可以提供对应的接口给上层,以此改善功能算法。以英飞凌tc3xx为例,如下所示:
通过BO位域和EP位域可以更准确的获悉节点状态,如下所示:
如果需要更进一步的知道Error Passive是TEC还是REC导致的,可以进一步读取错误计数寄存器(ECR)的RP位域,如下所示:
提示:REC使用7个Bit表示,最大可表示128,TEC用8个Bit表示,最大可表示256。
回到这个小节的问题:“测试中,为什么错误帧达到32帧,就会Busoff呢?可以大于32帧吗?”
如果要搞清楚发送多少错误帧会导致TEC>255,进而让节点进入Bus off状态,我们需要先清楚TEC的累加规则:
发送节点在发送时,产生错误标志,TEC + 8。注意,有两种工况除外:
第一、仲裁阶段,节点发送隐性位("1"),收到显性位("0")。当其他节点CAN ID小,优先级高时,低优先级(CAN ID大)的节点仲裁失败,发送的隐性位被显性位覆盖导致;
第二、节点处于Error Passive模式时,Ack Slot发送隐性位,收到隐性位(没有节点应带发送节点),说明当前总线只有一个节点在总线中,此时TEC不需要再累加;
发送节点在发送主动错误标志或者过载标志时,检测出位错误(Bit Error), TEC + 8;
节点从主动错误标志、过载标志的最开始检测出连续14个显性位。之后,每检测出连续8个显性位。TEC + 8;
被动错误标志后检测出连续8个显性位。TEC + 8;
发送节点正常发送完一帧数据,且被其他接收节点应答(Ack)。TEC - 1,如果TEC = 0,则保持0;
如果节点已经Busoff,当检测到128个连续11 bit隐性位时。TEC = 0。
通过如上规则可以看出,对于发送节点自身发送报文导致的错误,TEC均会累加8,也就是说,如果想最快地使得某个节点进入Bus off状态,就得让发送节点自己识别到自身产生的错误,而且,最少要产生32次,32*8 = 256 >255,节点进入Bus off状态。
有的时候看到总线错误不止32帧,节点才进入Busoff,又是因为什么呢?这里我们分析一种工况:
测试中,如果通过Capl脚本只是干扰节点(Node A)固定的CAN ID(eg:0x10),可能需要>32个错误帧,才能让Node A进入Bus off。一个项目中,一个节点的外发报文可以有多个。
假设:Node A有5个外发的周期性应用报文,CAN ID:0x01~0x20,周期都是10ms。测试中,只干扰CAN ID = 0x10的报文。
如上TEC计数规则中,节点每成功发送一帧报文,TEC会减1,由于Node A 的5个CAN报文周期相同,干扰0x10使得TEC + 8,但是,如果其余4个报文成功被发送,则每发送一帧,TEC - 1。这样就使得TEC不能很快的>255,进而错误帧的次数会超过32帧。所以,如果想快速的制造Bus off,可以对多有外发报文的某个Bit干扰,这样,可以连续的干扰出32个错误帧。
只干扰特定CAN ID报文,总线报文状态示意如下所示:
提示:一个错误帧中,可能有多种错误类型。
2、Bus off的DTC问题
当Bus off发生到一定程度时,会影响到总线的正常通信,需要将此故障信息记录下来,以便于后续问题排查。对于Bus off DTC的设计策略,每家OEM要求有所不同。本文,分享一种需求,供大家参考:
Busoff检测频率10ms。DTC一般会对应一个或者多个事件(Event),为了识别事件的状态,会约束一个检测频率,检测频率的大小,意味着事件发生故障时,能否被快速检测到,进而决定着事件对应的DTC能否被快速触发;
Busoff快恢复32次,快恢复周期10ms。当节点通信出现故障时,如果能快速恢复通信,节点功能也能及时恢复,所以,设计10ms的快恢复也就能理解。尝试32次,也是想尽可能地挽救故障节点的通信功能;
Busoff慢恢复NA(不做明确约束),慢恢复周期60s。当快恢复32次都不能有效挽救节点通信时,说明节点大概率出现了不可逆的故障。所以,设计一个较慢的慢恢复期,就是想再碰碰运气,万一节点通信又恢复了呢?如果节点不能恢复通信,车辆又不能立马停下,只能任其不断地尝试慢恢复,因此,不做慢恢复的约束。此时,同网段内的其他节点会监控对应的通信报文是否丢失,故障节点由于发生Busoff,非Busoff DTC的监控功能禁止;
Busoff发生32次,进入慢恢复期时,Bus off DTC Confirmation(Bit 3 = 1)。既然做了最大努力的尝试,节点不能恢复通信,为了便于后续的车辆检修,需要记录Bus off DTC;
Step Up = 4,32次Busoff后,4*32 >127,Step Down = 128。
相对于其他监控事件,Bus off 事件优先级(Event priority)一般较低,注意:1表示highest priorit,数字越大,事件的优先级越低。
这里需要讨论一个“连续”问题,Busoff发生32次,且Busoff由快恢复(Level1)进入慢恢复(Level2)阶段时,Busoff DTC需要上报。这里的32次如何计算呢?这里抛一个问题:”如上需求中,10ms可以检测一次节点Busoff状态,假设前100ms检测到了10次节点Busoff状态,中间1s节点恢复了通信,之后又快速的发生了32次Busoff,需要上报Busoff DTC吗?“,如下所示:
如上的问题就涉及到了一个问题:”Busoff次数如何累加?“,对于这个问题的答案,需要结合项目需求,和甲方明确好。每家OEM的约束不同,这里讨论一种约束工况:以10ms检测频率为基准,如果20ms的检测周期内没有检测到Busoff,则Busoff CNT不再累加,重置Busoff CNT(Busoff CNT = 0),因为此时的Busoff不是"连续"的。
作者:佚名