提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
提示:本编文章仅供学习
一、错误帧的帧结构
在发送和接收报文时,总线上的节点如果检测出了错误,那么该节点就会发送错误帧,通知总线上的节点,自己出错了。
错误帧由错误标志和错误界定符两个部分组成。
- 主动错误标志:6个连续的显性位;
- 被动错误标志:6个连续的隐性位;
- 错误界定符:8个连续的隐性位。
可以看到在错误标志之后还有0~6位的错误标志重叠,这一段最低有0个位,最多有6个位,关于这一段是怎么形成的,将在下文中解释。
二、错误检测
2.1 位填充原则
在了解CAN总线中的错误检测之前,首先需要了解什么是位填充。
CAN协议中规定,当相同极性的电平持续五位时,则添加一个极性相反的位。
-
对于发送节点而言:
在发送数据帧和遥控帧时,对于SOF~CRC(除去CRC界定符) 之间的位流,相同极性的电平如果持续5位,那么在下一个位插入一个与之前5位反型的电平; -
对于接收节点而言:
在接收数据帧和遥控帧时,对于**SOF~CRC(除去CRC界定符)**之间的位流,相同极性的电平如果持续5位,那么需要删除下一位再接收。
2.2 错误的种类
在CAN总线通信中,一共有五种错误:
- 位错误
- ACK错误
- 填充错误
- CRC错误
- 格式错误
2.2.1 位错误(Bit Check Error)
节点将自己发送到总线上的电平与同时从总线上回读到的电平进行比较,如果发现二者不一致,那么这个节点就会检测出一个位错误。
2.2.2 ACK错误 (Acknowledgment Error)
按照CAN协议的规定,在一帧报文(数据帧或者遥控帧)发出之后,如果接收节点Node_B成功接收了该帧报文,那么接收节点Node_B就要在该帧报文ACK槽对应的时间段内向总线上发送一个显性位来应答发送节点Node_A。这样发送节点Node_A就会在ACK槽时间段内从总线上回读到一个显性位。因此:
当发送节点Node_A在ACK槽时间段内没有回读到显性位,那么发送节点Node_A就会检测到一个ACK应答错误。这表示没有一个节点成功接收该帧报文。
2.2.3 填充错误(Fill Error)
在需要执行位填充原则的帧段(数据帧遥控帧的SOF~CRC序列),检测到连续六个同性位,则检测到一个填充错误。
2.2.4 CRC错误
发送节点Node_A在发送数据帧或者遥控帧时,会计算出该帧报文的CRC序列。接收节点Node_B在接收报文时也会执行相同的CRC算法,如果接收节点Node_B计算出的CRC序列值与发送节点Node_A发来的CRC序列值不一致,那么接收节点就检测到一个CRC错误。
2.2.5 格式错误
在一帧报文发送时,如果在必须发送预定值的区域内检测到了非法值,那么就检测到一个格式错误。
CAN报文中,有预定值的区域包括:
- 数据帧和遥控帧的CRC界定符、ACK界定符、EOF;
- 错误帧界定符
- 过载帧界定符
3错误通知
上一节中,讲到CAN通信中有五种错误,并且介绍了在什么情况下能够检测到这几种错误,在检测到错误之后,检测到错误的节点就要发送错误帧到总线上来通知总线上的其他节点。
错误帧有的带有主动错误标志,有的带有被动错误标志,而且错误标志重叠部分的字节数也不一样,那么问题就来了:
- 什么情况下发送带有主动错误标志的错误帧;
- 什么情况下发送带有被动错误标志的错误帧;
- 在哪个时间点发送错误帧;
- 错误标志重叠部分是怎样形成的;
3.1节点错误状态
按照CAN协议的规定,CAN总线上的节点始终处于以下三种状态之一。
- 主动错误状态
- 被动错误状态
- 总关闭状态
当满足一定的条件时,节点可以从一种状态转换为另外一种状态。
1)主动错误状态
-
节点处于主动错误状态可以正常通信;
-
处于主动错误状态的节点(可能是接收节点也可能是发送节点)在检测出错误时,发出主动错误标志。
2)被动错误状态 -
节点处于被动错误状态可以正常通信;
-
处于被动错误状态的节点(可能是接收节点也可能是发送节点)在检测出错误时,发出被动错误标志。
3)总线关闭状态 -
节点处于总线关闭状态,那么该节点不能收发报文;
-
处于总线关闭状态的节点,只能一直等待,在满足一定条件的时候,再次进入到主动错误状态。
3.2 错误状态的转换
现在我们知道:
- 处于主动错误状态的节点在检测到错误时会发送带有主动错误标志的错误帧;
- 处于被动错误状态的节点在检测到错误时会发送带有被动错误标志的错误帧。
那么一个CAN节点在什么情况下处于主动错误状态,什么情况下处于被动错误状态呢?
根据CAN协议的规定,在CAN节点内,有两个计数器:发送错误计数器(TEC)和接收错误计数器(REC)。
CAN节点错误状态的转换,就是基于这两个计数器来进行的。
可以看出,节点错误状态的转换就是一个**“量变”到“质变”的过程:
1) 主动错误状态
最开始TCE和REC都小于127时,就处于主动错误状态。
在这一状态下,节点检测到一个错误就会发送带有主动错误标志的错误帧,因为主动错误标志是连续六个显性位,所以这个时候主动错误标志将会“覆盖”掉总线上其它节点的发送,而之前在CAN总线上传输的报文就被这“六个连续显性位”破坏掉了。
2)被动错误状态
如果某个节点发送错误帧的次数较多,必将使得TCE>127 或者 REC>127,那么该节点就处于被动错误状态。
在这一状态下,节点Node_A检测到一个错误就会发送带有被动错误标志的错误帧,因为被动错误标志是连续六个隐性位,所以这个时候总线上正在传输的报文位流不会受到该被动错误帧的影响,其它的节点该发送的发送,该接收的接收,没人搭理这个发送被动错误帧的节点Node_A。
3)总线关闭状态
如果一个处于被动错误状态的节点,仍然多次发送被动错误帧,那么势必导致TEC > 255,这样就处于总线关闭状态。
在总线关闭状态下的节点Node_A不能向总线上发送报文,也不能从总线上接收报文,整个节点脱离总线。等到检测到128次11个连续的隐性位时,TEC和REC置0,重新回到主动错误状态。
按照我的理解这个所谓“检测到128次11个连续隐性位”其实就是让这个节点隔离一段时间冷静下,因为它一旦处于总线关闭状态,就不会和总线有任何的联系,这个时候只要它计算时间等于达到传送128次11个连续隐性位所用的时间,就可以重新连到总线上。
3.3 错误帧的发送
在检测到错误之后,什么时候发送错误帧呢?
按照CAN协议的规定:
- 位错误、填充错误、格式错误、ACK错误。
在错误产生的那一位的下一位开始发送错误帧。 - CRC错误
紧随ACK界定符后的位发送错误帧。
例子1:
(1)发送节点Node_A发送一个显性位,但是却从总线上听到一个隐形位,于是Node_A节点就会检测到一个位错误;
(2)Node_A检测到位错误之后,立即在下一位开始发送主动错误帧:6个连续显性位的主动错误标志+8个连续隐性位的错误界定符;
(3)对应Node_A发出的主动错误标志,总线上电平为6个连续显性位;
(4)接收节点Node_B和Node_C从总线上听到连续6个显性位,那么就会检测到一个填充错误,于是这两个节点都会发送主动错误帧;
(5)对应Node_B和Node_C发出的主动错误标志,总线电平又有6个连续显性电平,对应Node_B和Node_C发出的错误界定符,总线电平有8个连续的隐性电平。
(6)在间歇场之后,Node_A节点重新发送刚刚出错的报文。
例子2:
从上图中可以看出错误帧之中,错误标志重叠部分是怎样形成的,这个例子中,位错误的错误标志与填充错误的错误标志重叠两位,剩下的部分还有四位: