错误检测和管理
在总线上发送或者接收数据时,若通信节点检测到错误,会主动发起错误帧。前面章节介绍到错误帧除了发送 6Bit 的错误标志外,可能会有 0 ~ 6 Bit 的错误标志重叠的情况。在介绍错误帧之前,首先需要了解 ISO 11898 标准中的位填充、错误类型及错误处理机制。
位填充 (Bit Stuffing)
ISO 11898 协议中规定,信号同步方式依赖于信号的边沿跳变,如果数据流中连续出现大量相同的逻辑电平(例如连续的 '1' 或连续的 '0'),会导致信号长时间不翻转。接收端此时将无法同步,导致采样点漂移,通信出错。 为解决上述问题,需要进行位填充,具体规则如下:
发送节点逻辑:在发送数据帧和远程帧时,在 SOF ~ CRC 字段内检测到连续 5 个相同极性的位时,会在其后自动插入一个极性相反的填充位(Stuff Bit)。
接收节点逻辑:在接收数据帧和远程帧时,在 SOF ~ CRC 字段内解码数据流时,如果检测到连续 5 个相同极性的位,会自动剔除(De-stuff)随后的那一个相反极性的位,从而恢复原始数据。如果第 6 为位电平和前 5 位相同,则视为填充错误。
示意图如下,填充标志位用橘色色块标记:
位填充示意图
错误类型
常见的错误类型如下表所示:
错误种类 |
错误原因 |
错误的检测范围 |
错误帧发送时机 |
检测单元 |
|---|---|---|---|---|
位错误 |
比较输出电平和总线电平(不含填充位),当两电平不一样时所检测到的错误。 |
|
下一位期间 (在检测到位错误的位之后,立即开始发送错误标志) |
发送单元 |
填充错误 |
在需要位填充的段内,连续检测到 6 位相同的电平时所检测到的错误。 |
|
下一位期间 (在检测到第 6 个连续相同位的时刻,立即开始发送错误标志) |
接收单元 |
CRC 错误 |
从接收到的数据计算出的 CRC 结果与接收到的 CRC 序列不同时所检测到的错误。 |
|
ACK 界定符之后 (在 ACK 界定符位之后,即 EOF 的第一位位置开始发送) |
接收单元 |
格式错误 |
检测出与固定格式的位段相反的格式时所检测到的错误。 |
|
下一位期间 (例外:如果是在 CRC 界定符检测到的格式错误,看作 CRC 错误,在 ACK 界定符后发送) |
发送单元 接收单元 |
ACK 错误 |
发送单元在 ACK 槽 (ACK Slot) 中检测出隐性电平时所检测到的错误(未收到接收节点的 ACK 显性电平 0)。 |
|
ACK 界定符之后 (在 ACK 界定符位之后,即 EOF 的第一位位置开始发送) |
发送单元 |
错误帧发送时机:
立即发送 (Next Bit):
位错误、填充错误、格式错误(绝大多数情况)一旦被检测到,节点会在下一位立即破坏当前传输,发送错误帧。这保证了数据的一致性,防止错误的扩散。
延迟发送 (After ACK Delimiter):
CRC 错误和 ACK 错误是在 ACK 界定符之后才发送错误帧。
CRC 错误: 接收节点虽然在 CRC 校验阶段就算出了错误,但它不会立即报错,而是会先发送一个 ACK(如果格式正确),或者不发送 ACK,等到 ACK 界定符结束后,才在 EOF 阶段拉低总线报错。这样做是为了不破坏其他可能正确接收到数据的节点的 ACK 过程。
ACK 错误: 发送节点发现没人应答(ACK Slot 为隐性),它会在 ACK 界定符之后发送错误帧。
备注
位错误不会发生在 ID 仲裁段、 ACK 槽以及发生被动错误时:
ID 仲裁阶段如果发送 1 但是收到 0,则认为仲裁丢失
ACK 槽位,发送端发送隐性电平 1,读回时仍然是 1,表明未收到应答
节点发送被动错误标志(连续 6bit 隐性位),却回读到显性位,不认为是位错误。
在 EOF 最后 1 bit 出现显性位,发送过载帧,而不是错误帧。
发送节点的产生错误一般有:位错误、格式错误、ACK 错误
接收节点的产生错误一般有:填充错误、格式错误、CRC 错误
错误处理机制
当 CAN 通信节点检测到错误时,根据内部错误计数器(TEC 和 REC)的数值变化,会在以下三种状态之间自动切换。
错误状态跳转
备注
TEC: 发送错误计数器 (Transmit Error Counter)
REC: 接收错误计数器 (Receive Error Counter)
下表总结了各状态的进入条件及行为特性。
错误状态 |
进入条件 (阈值) |
错误标志类型 |
通信与行为特性 |
|---|---|---|---|
主动错误 (Error Active) |
TEC ≤ 127 且 REC ≤ 127 |
主动错误标志 (6 个连续显性位) |
|
被动错误 (Error Passive) |
TEC > 127 或 REC > 127 |
被动错误标志 (6 个连续隐性位) |
|
总线关闭 (Bus Off) |
TEC > 255 |
无 (禁止发送) |
|
错误计数器的变动在检测到错误标志的 第一位 时触发,一次数据发送/接收可能同时满足多个条件,错误计数值可能被多次调整。下表列出了计数规则变动条件:
序号 |
触发条件 |
TEC |
REC |
|---|---|---|---|
1 |
接收器检测到错误(在发送主动错误标志或过载标志期间检测到的位错误除外)。 |
— |
+1 |
2 |
接收器在发送错误标志后,检测到的第一个位为显性位。 |
— |
+8 |
3 |
发送器发送错误标志。 |
+8 |
— |
4 |
发送器在发送主动错误标志或过载标志期间检测到位错误。 |
+8 |
— |
5 |
接收器在发送主动错误标志或过载标志期间检测到位错误。 |
— |
+8 |
6 |
任何节点在发送错误标志或过载标志后,检测到过量的连续显性位:
|
+8 |
+8 |
7 |
发送器成功发送一帧(成功获得 ACK 并且直到 EOF 完成都没有错误)。 |
若 > 0 则 -1; 若 = 0 则不变 |
— |
8 |
接收器成功接收一帧(在 ACK 槽之前无错误,且成功发送显性 ACK 位)。 |
— |
若 1 ≤ REC ≤ 127,则 -1; 若 = 0,则不变; 若 > 127,置为 119 ~ 127 之间 |
10 |
总线关闭恢复(检测到 128 次 × 11 个连续隐性位) |
置 0 |
置 0 |
第三种情况存在例外:
发送器处于被动错误状态,因 ACK 槽未检测到显性位产生 ACK 错误,且在发送被动错误标志时未检测到显性位。
发送器因仲裁期间的填充错误发送错误标志(除非该违规位本应是隐性但被监测为显性,此时 TEC 仍增加 8)。
发送错误帧
错误标志未重叠:下图 错误标志未重叠 展示了节点 A 发送时检测到“位错误”,然后节点 B 检测到连续 6 个相同的显性电平产生“填充错误”,此时总线上节点 A 的错误标志位和节点 B 的错误标志位并未重叠
错误标志未重叠
错误标志重叠:下图 错误标志重叠 展示了节点 A 产生了“位错误”,节点 B 检测到连续 6 个相同的显性电平,产生填充错误。两个节点的主动错误标志重叠 2 位,剩下部分还有 4 位。
错误标志重叠
发送过载帧
过载帧的标志位是连续 6Bit 的显性电平 0,会破坏总线上其他节点的发送过程,导致其他节点不能正常发送报文,变相推迟了其他节点的发送。 以下三种情况下需要发送过载帧:
接收节点内部未就绪:接收节点由于自身处理速度限制或缓冲区限制,尚未准备好接收下一帧数据,会在帧间隔(Intermission)的第一位发送过载帧,强行拉长空闲时间。
接收节点在帧间隔(Intermission)的第 1 位或第 2 位检测到显性位 :正常的帧间隔应至少包含 3 个连续的隐性位。若在前两位出现显性位,通常意味着有节点提前发送了报文(时序错误)或总线出现了干扰。此时节点会发送过载帧来处理这种异常同步。
接收节点在错误界定符 (Error Delimiter) 或 过载界定符 (Overload Delimiter) 的 第 8 位(最后一位)检测到了显性位 (Dominant, 0):界定符的标准格式是 8 个连续的隐性位。如果在最后一位检测到显性位,被视为下一帧报文过早开始(或者前一帧未能正确结束)。在这种特定情况下触发的过载帧,不会增加节点的错误计数器。
帧结束 (EOF) 最后一位检测到显性位 :由于 EOF 前 6 位已通过检查,协议判定 当前帧接收有效 (Valid),不作为格式错误处理。
备注
错误计数器:过载帧的发送是“无害”的,它 不会 增加节点的发送错误计数器 (TEC) 或接收错误计数器 (REC)。
数量限制:为了防止总线被永久阻塞,控制器通常限制连续发送过载帧的次数(通常最多允许 2 帧延时)。