点击蓝字
关注我们
点击蓝字
关注我们
点击蓝字
一、CAN总线错误检测机制

在CAN里面,当某一个节点检测到错误之后,会以发送错误帧的方式告知其他参与通信的节点,当前正在发送或正在接收的数据是有问题的,错误帧的格式是由6个bit的错误标志位和8个bit的错误界定符组成,在发送完错误帧之后,发送节点会有一个自动纠错的机制,会重发出错的数据
从发送节点和接收节点两个角度来看

对于发送节点来说,采用的手段主要是位监控跟ACK Check。
位监控:位监控就是检查我发送的数据跟我从总线上回读的数据是否一致,如果出现发0读1或发1读0,就会认为这是一个错误,位监控的范围是从SOF开始,到EOF结束(不包含仲裁场和ACK位)。
ACK Check:发送节点在报文传输至ACK槽(ACK Slot)时,会主动监听总线电平状态。标准规定,成功接收报文的节点应在ACK槽内回馈一个显性位(逻辑0)。若发送节点此时检测到总线仍为隐性位(逻辑1),即判定为ACK错误。此错误表明无任何节点成功接收该报文。根本原因可能包括:物理层故障:如总线断路、接收节点离线。检测到ACK错误后,发送节点自动重发报文。
对于接收节点,有填充检查、格式检查、CRC检查、ACK位监控。
填充检查:发送节点进行位填充,每5个极性相同的位就会插入一个极性相反的位,接收节点接收完数据后自动清除位填充(若发送节点发0000010,接收节点接收000000),如果说接收节点在接收数据的过程中,在SOF到CRC的范围内检测到了连续6个极性相同的位,会报一个Stuff error。
格式检查:格式检查是对CRC_DEL、ACK_DEL以及EOF,这几个位它们都是固定格式为1,如果监测到0,会报格式错误。
CRC检查:接收节点计算的CRC校验值与报文中的CRC序列不一致,表明单个接收节点的数据完整性校验失败,但其他节点可能仍能正确接收(数据传输过程中可能受到电磁干扰、信号衰减等随机干扰,导致单个节点接收到的数据位发生翻转。若干扰仅影响特定节点接收链路,而其他节点未受影响,则会出现部分节点校验失败的情况)
ACK-Bit Monitoring:ACK这一位是由接收节点发送的,接收节点在给完肯定应答之后,会回读总线上ACK的,如果接收节点发送的是0,回读的是1,则在下一位发错误帧
在CAN总线通信中,ACK错误和CRC错误并非必然同时产生。
同时产生的场景:
若某接收节点因CRC校验失败而丢弃报文,且无其他节点正确接收,则发送节点将因未收到ACK应答而触发ACK错误。此时两者均被记录,但本质是CRC错误导致ACK错误
独立发生场景:
仅ACK错误:总线物理层完全中断(如所有接收节点离线),发送节点因无应答触发ACK错误,但无接收节点执行CRC校验,导致只有ACK错误。
仅CRC错误:总线存在多个接收节点时,部分节点因数据干扰触发CRC错误,但其他正常节点仍会发送ACK应答,故发送节点不会检测到ACK错误。
错误处理差异
ACK错误:发送节点自动重传报文,并累加发送错误计数器(TEC)
CRC错误:接收节点丢弃错误帧,累加接收错误计数器(REC),但不主动通知发送节点。
二、错误帧发送的原则

当错误被检测到之后,错误帧会在下一位立马发出来,除了CRC错误,因为CRC错误不会立马发错误帧,它会在ACK位发1,给一个否定应答,然后在ACK_DEL之后才会发送CRC错误帧,除了CRC错误、前面的提到的位错误,格式错误、填充错误等等,立马会在下一位发送错误帧

错误帧的格式由错误标志位和错误界定符组成,错误标志位由于节点所处的状态不一样,它发送的错误标志的格式也会有所区别。
2.1 错误状态转换

节点通过REC(接收错误计数器)和TEC(发送错误计数器)值,来实现节点错误状态的转换。
当接收错误产生时REC增加,正确接收到数据帧时,REC减少(计数器的增加和减少不是简单的加1减1,会根据不同的错误类型,加的值不一样),在发送错误产生时TEC增加,正确发送数据帧,TEC减少。
根据REC和TEC的值,主要有三种状态:主动错误、被动错误、Bus Off。
主动错误状态Error Active:刚运行时就处于主动错误状态,因为计数器都为0,或者很小的值,正常的进行总线通信,错误产生时,发送主动错误标志(6个连续显性位)。
被动错误状态Error Passive:如果一直有错误,可能节点自身有问题,则需要发6个连续的隐性位,以免破坏总线正常传输,被动错误状态的节点能够进行总线通信。当计数器大于255时,该节点进行总线关闭(bus off),脱离总线,对于软件而言进入busoff就是先关掉控制器,进行重启,重启之后,又开始进入主动错误状态,重新进行通信
Bus Off:不能收发任何报文
主动错误和被动错误的区别在于:
主动错误:检测到错误,立即主动发送错误标志,6个连续的显性位
被动错误:检测到错误,只能“被动地”等其他的节点报错,发送6个连续隐性位,(隐性位可能被其他节点的显性位覆盖),诱发接收节点发送错误标志,直到识别出其他节点主动报错
具体来说,当一个节点处于Error-Active,主动错误状态,会发6个0再加后面8个1的错误界定符,如果一个主动错误节点检测到一个错误之后,发了6个0,8个1之后,这个时候其他的节点也可能检测到一个错误,也会发6个0、8个1,所以在真实总线上看到的错误帧,它的错误标志位可能不止6个0,比如6到12个0,这都是有可能的

当处于Error-Passive的节点,会发6个1的错误标志位,再加上8个1的错误界定符,因为1在总线上是隐性状态,会被其他的0给覆盖掉,所以它的这个错误标志不会被其他的节点所发现,只能等到有其他处于主动错误状态的接收节点也同样检测到一个错误之后,发6个0的错误标志位,来告知其他节点
三、举个例子
先假设所有节点都处于主动错误状态,就是说它们在检测到错误之后,都会发6个0加8个1。

下图所示,发送节点在发送数据的过程中,在某一位,原本需要发送的数据是0,但是实际总线上是1,所以对于发送节点来说,会根据位监控的机制,发和读不一致,会在下一个bit停止数据的发送,会发送一个错误帧,会发6个0,后面加8个1

但是在这一位,接收节点接收到的是1,因为它不知道发送节点发送的是0还是1,所以这个时候,接收节点没有察觉到有任何问题,会继续接收总线上的数据,直到连续接收到了6个0,因为有填充规则,对于接收节点来说,检测到了一个填充错误,在下一个bit,接收节点就会发错误帧,会发6个0,后面再加8个1

这个时候可以看到在实际总线上表现出来的错误帧,它的错误标志位可能就不止6个0,可能是发送节点的错误标志位,跟接收节点发送的错误标志位的叠加,可能最多出现12个0,后面是8个1的错误界定符,错误界定符之后,后面再加3个bit的帧间隔,构成连续11个1的隐性位,连续11个1表示总线又进入到了空闲状态,由于自动纠错的机制在,发送节点会将之前的这帧数据再去进行重发,CAN当中,这种错误是成对出现的,当某一个节点检测到一个错误之后,必然会引发其他节点也会检测到一个错误,最终所有参与通信的节点都会发错误帧,所有节点都会将当前正在发送或正在接收的数据丢弃掉,保证总线在数据传输过程中的数据一致性

处于主动错误状态的节点其实就是正常工作的状态,可以该发发,该收收,没有任何影响,但是对于处于被动状态的发送节点,在CAN协议里面规定,是不允许在3个bit的帧间隔之后总线进入空闲,必须要额外等待8个bit的延迟之后,才允许往总线上发送数据,所以对于一个被动错误状态的节点,在这8个bit的等待过程中,如果有其他主动节点请求访问总线,这个主动节点就会优先发送数据,这也相当于对进入被动错误状态节点的一个小小的惩罚措施,毕竟当一个节点进入被动错误状态,或多或少说明这个节点存在一些问题


*免责声明:本文由作者原创或转发。如无意中侵犯了某方的知识产权,告之即删。以上图文来源于网络,如有侵权,请及时联系我们,我们将在24小时内删除。文章内容系作者个人观点,汽车以太网技术研究实验室转载仅为了传达一种不同的观点,不代表汽车以太网技术研究实验室对该观点赞同或支持,如果有任何异议,欢迎联系汽车以太网技术研究实验室。
原文链接:
https://blog.csdn.net/m0_47532508/article/details/150564984

