错误处理机制
CAN 的可靠性传奇,靠的是一套精密的差错检测与故障界定机制。本章讲透五种错误、错误帧、TEC/REC 计数器与"错误主动→被动→总线关闭"三态状态机。
CAN 的可靠性传奇,靠的是一套精密的差错检测与故障界定机制。本章讲透五种错误、错误帧、TEC/REC 计数器与"错误主动→被动→总线关闭"三态状态机。
| 错误类型 | 检出者 | 触发条件 | 典型原因 |
|---|---|---|---|
| 位错误 Bit | 发送方 | 发出电平≠回读电平(仲裁/ACK 除外) | 硬件故障、多驱动冲突 |
| 填充错误 Stuff | 收发双方 | 需填充区出现 6 连同 | 干扰、错误帧标志 |
| CRC 错误 | 接收方 | 重算 CRC≠帧内 CRC | 数据场位翻转 |
| 形式错误 Form | 收发双方 | 固定隐性位出现显性 | 界定符/EOF 被破坏 |
| 应答错误 ACK | 发送方 | ACK 槽读回隐性(无人应答) | 孤立节点、波特率不符 |
这五种检测互为补充:CRC 抓数据内容错误,位/形式错误抓电平级异常,填充错误兼顾同步与内容,ACK 错误确认送达。它们让 CAN 的残余错误概率(未检出错误)极低(约 10−11 量级)。一旦任一检测命中,检出节点立即发错误帧作废本帧,发送方随后自动重传——错误恢复对上层应用几乎透明。
节点根据 TEC/REC 在三种状态间转移。核心阈值是 128(主动↔被动)与 256(进入总线关闭)。
| 状态 | 进入条件 | 能否收发 | 错误标志 | 对总线影响 |
|---|---|---|---|---|
| 错误主动 | TEC≤127 且 REC≤127 | 正常收发 | 6 显性位 | 正常参与,出错会打断总线 |
| 错误被动 | TEC>127 或 REC>127 | 可收发但受罚 | 6 隐性位 | 出错不搅局,发送后额外等待 |
| 总线关闭 | TEC≥256 | 完全退出 | 无 | 自我隔离,不影响其它节点 |
当一个节点反复发送失败(TEC 累加到 ≥256),它进入总线关闭,主动闭嘴、不再干扰总线,这样即使它硬件损坏也不会拖垮整个网络。恢复需要满足条件(总线上出现 128 次连续 11 个隐性位,即总线恢复正常一段时间)并由软件重新初始化 CAN 外设。在实际项目里,进入 Bus-Off 通常意味着严重物理问题(终端电阻缺失、波特率错配、线路短路),应记录诊断故障码并触发恢复流程,而不是简单地无限重启。
在 STM32 HAL 中可读取错误计数器并处理 Bus-Off 恢复:
/* 读取错误状态与计数器 */ uint32_t esr = CAN1->ESR; /* Error Status Register */ uint8_t tec = (esr >> 16) & 0xFF; /* 发送错误计数器 TEC */ uint8_t rec = (esr >> 24) & 0xFF; /* 接收错误计数器 REC */ if (esr & CAN_ESR_BOFF) { /* 已进入总线关闭 */ /* 记录诊断故障码,排查物理层 */ log_dtc(DTC_CAN_BUSOFF, tec, rec); /* 恢复:ABOM=1 可自动恢复;否则手动重启外设 */ HAL_CAN_Stop(&hcan); HAL_CAN_Start(&hcan); /* 重新进入总线 */ } else if (esr & CAN_ESR_EPVF) { /* 错误被动标志 */ /* 告警:链路质量下降,TEC/REC 超过 127 */ warn_link_degraded(tec, rec); }
bxCAN 的 MCR.ABOM(Automatic Bus-Off Management)位置 1 时,控制器在进入 Bus-Off 后会自动等待恢复条件满足并重新上线,无需软件干预。置 0 则需软件手动 Stop/Start。生产代码常开启 ABOM 以保证瞬时故障后自动复位,但同时应记录 Bus-Off 次数用于诊断——频繁 Bus-Off 是硬件问题的强信号。
CAN 用五种错误检测构筑可靠性:位错误(发送电平≠回读,仲裁/ACK 除外)、填充错误(需填充区 6 连同)、CRC 错误(重算 CRC 不符)、形式错误(固定隐性位出现显性)、应答错误(ACK 槽无人覆写显性)。任一命中,检出节点立即发错误帧——主动错误标志是 6 个显性位,故意违反位填充让全网一致检错并丢弃该帧,发送方随后自动重传,对上层透明。每个节点维护 TEC/REC 两个计数器(出错涨得快、正常降得慢),驱动故障界定三态状态机:TEC/REC≤127 为错误主动(正常,发显性错误标志);超 127 转错误被动(仍收发但发隐性错误标志、发送后额外等待受罚);TEC≥256 进入总线关闭(彻底自我隔离保护全网,需总线恢复正常且软件重初始化才能回到主动态)。ABOM 位可让 bxCAN 自动恢复。频繁 Bus-Off 往往指向终端电阻缺失、波特率错配或线路短路等严重物理问题,应记录诊断码而非盲目重启。