☰
CAN 技术系列 06 · CAN 错误处理与错误帧
2026/10/31 22:27:00 网站建设 项目流程

📚 CAN总线技术系列 · 持续更新中

本系列从差分电气层一路打到 Linux SocketCAN,把"两根线"背后的电气/协议/控制器/驱动/实战全拧成一根线。

👉 想系统追更,戳这里查看完整专栏:
【CAN 技术系列】
👉 其他技术系列专栏,欢迎关注、交流、共同成长:
【SPI 技术系列】 【I2C 技术系列】 【串口技术系列】【RISC-V 架构系列】【Linux内核系列】 【操作系统设计思想系列】 【 Android 系统全景专栏】


本篇定位:CAN 协议层最强大的特性——错误处理。CAN 有 5 种错误检测、错误计数器、节点状态机(主动/被动/总线关闭)、错误帧自动破坏错帧。本篇讲清错误检测、错误帧、错误计数器、状态转移。读完你理解 CAN 为什么是汽车级可靠,以及总线关闭怎么恢复。

错误处理是 CAN 汽车级可靠的根基
SPI 无 ACK 无错误检测。I2C 只有 ACK/NACK。CAN 有 5 种错误检测 + 错误计数器 + 错误帧 + 自动重发 + 总线关闭——这是汽车级可靠的协议层保障。理解错误处理,才算懂 CAN。功能安全芯片,总线关闭恢复是必考。对照 [[10-SPI错误处理与恢复]] 和 [[10-I2C错误处理与恢复]] 看,CAN 的错误处理远比 SPI/I2C 完备。


目录

  • 一、五种错误检测
    • 1.1 位监控错误(Bit Monitoring)
    • 1.2 位填充错误(Stuff Error)
    • 1.3 CRC 错误(CRC Error)
    • 1.4 格式错误(Form Error)
    • 1.5 ACK 错误(ACK Error)
    • 1.6 检测总结
  • 二、错误帧
    • 2.1 错误帧结构
    • 2.2 主动错误标志(Active Error Flag)
    • 2.3 被动错误标志(Passive Error Flag)
    • 2.4 错误定界符(Error Delimiter)
    • 2.5 错误帧作用
  • 三、错误计数器
    • 3.1 两个计数器
    • 3.2 计数规则
    • 3.3 计数器特性
    • 3.4 计数器读取
  • 四、节点状态机
    • 4.1 三种状态
    • 4.2 状态转移
    • 4.3 主动错误(Error Active)
    • 4.4 被动错误(Error Passive)
    • 4.5 总线关闭(Bus-Off)
  • 五、自动重发
    • 5.1 自动重发机制
    • 5.2 重发时机
    • 5.3 单次发送模式
    • 5.4 重发的问题
  • 六、总线关闭恢复
    • 6.1 总线关闭状态
    • 6.2 自动恢复
    • 6.3 软件恢复
    • 6.4 恢复策略
    • 6.5 功能安全考量
  • 七、错误中断与处理
    • 7.1 错误中断源
    • 7.2 错误处理流程
    • 7.3 错误统计
  • 八、关键问题 Q&A
    • Q1:CAN 五种错误检测分别什么时候触发?
    • Q2:错误计数器怎么涨?为什么错+8 成功-1?
    • Q3:主动错误和被动错误有什么区别?
    • Q4:总线关闭怎么恢复?
    • Q5:CAN 自动重发,什么时候停?
    • Q6:错误计数器怎么看?
  • 九、实战案例
      • 案例 1:总线关闭,节点失联
    • 案例 2:错误被动,通信降级
    • 案例 3:ACK 错误,单节点自测
    • 案例 4:EMI 导致位填充错误
    • 案例 5:总线关闭无限恢复循环
    • 案例 6:高优先级帧重发,低优先级饿死
    • 案例 7:CRC 错误,采样点不一致
    • 案例 8:格式错误,EOF 被干扰
  • 十、本篇小结与速查
    • 核心要点
    • 错误检测速查
    • 状态机速查
    • 错误处理流程
    • 功能安全 CAN 错误处理清单
  • 延伸阅读
  • 参考资料

一、五种错误检测

CAN 有 5 种硬件错误检测,覆盖位级到帧级:

1.1 位监控错误(Bit Monitoring)

  • 节点发的位,读回总线比对
  • 发显性读到隐性 / 发隐性读到显性(除仲裁区隐性读显性是输)
  • 不符 → 位错误

1.2 位填充错误(Stuff Error)

  • 连续 5 同电平后必须有填充位(反向)
  • 6 个连续同电平 → 位填充错误

1.3 CRC 错误(CRC Error)

  • 接收方重算 CRC,和发送方比对
  • 不符 → CRC 错误

1.4 格式错误(Form Error)

  • 固定格式的位(CRC界定符/ACK界定符/EOF/IFS)应为隐性
  • 这些位出现显性 → 格式错误

1.5 ACK 错误(ACK Error)

  • 发送方在 ACK 间隙发隐性
  • 读到隐性(无节点应答)→ ACK 错误

1.6 检测总结

错误检测方时机
位监控发送方每个发位
位填充接收方仲裁段+CRC前
CRC接收方CRC段
格式接收方定界符/EOF/IFS
ACK发送方ACK间隙

二、错误帧

2.1 错误帧结构

错误标志(6位) + 错误定界符(8位隐性)

2.2 主动错误标志(Active Error Flag)

  • 主动错误节点发:6 个连续显性位
  • 破坏当前帧(覆盖数据,所有节点检测到错误)
  • 6 个显性可能被其他错误节点叠加,变长(< 12 位)

2.3 被动错误标志(Passive Error Flag)

  • 被动错误节点发:6 个连续隐性位
  • 不强制破坏当前帧(隐性不覆盖)
  • 其他节点可能正常接收,被动节点自己退出

2.4 错误定界符(Error Delimiter)

  • 8 个连续隐性位
  • 错误帧结束
  • 之后总线闲,可重发

2.5 错误帧作用

  • 检测到错误的节点发错误帧
  • 主动错误帧破坏当前帧,所有节点丢弃
  • 发送方重发(自动)

三、错误计数器

3.1 两个计数器

计数器含义
TEC(Transmit Error Counter)发送错误计数
REC(Receive Error Counter)接收错误计数

3.2 计数规则

发送方:

  • 发送错(ACK错/位错)→ TEC +8
  • 发送成功 → TEC -1(到 0 为止)

接收方:

  • 接收错(CRC/格式/填充)→ REC +8
  • 接收成功 → REC -1(到 0 为止)

主动错误标志期间:

  • 检测到显性位(其他节点也错)→ TEC/REC +1(少加,因为是别人错)

3.3 计数器特性

  • 错误增 8,成功减 1(错比对影响大)
  • 设计:偶发错误快速恢复,持续错误快速降级
  • 范围:0~255

3.4 计数器读取

  • 控制器寄存器(STM32 CAN_ESR 的 TEC/REC 字段)
  • Linux:ip -s link show can0看错误统计
  • 调试必看

四、节点状态机

4.1 三种状态

状态TEC/REC行为
主动错误(Error Active)< 96正常 + 主动错误标志(6显性)
被动错误(Error Passive)96~127通信 + 被动错误标志(6隐性) + 帧间多等
总线关闭(Bus-Off)TEC ≥ 128不通信(完全隔离)

4.2 状态转移

TEC/REC < 96 ┌─────────────────────┐ ↓ │ ┌─────────────┐ TEC/REC ≥ 96 ┌─────────────┐ │ 主动错误 │ ────────────→ │ 被动错误 │ │ (Error Active)│ │ (Error Passive)│ └─────────────┘ ←──────────── └─────────────┘ ↑ │ TEC/REC < 128(恢复) │ │ └──────────────────────────┘ │ │ │ TEC ≥ 128 │ TEC ≥ 255 │ (持续错误) ↓ │ ┌─────────────┐ │ │ 总线关闭 │ │ │ (Bus-Off) │ │ └─────────────┘ │ │ │ 恢复(128×11显性)│ └──────────────────┘

4.3 主动错误(Error Active)

  • 正常状态,通信正常
  • 错误时发主动错误标志(6 显性,破坏当前帧)
  • TEC/REC < 96

4.4 被动错误(Error Passive)

  • 通信仍进行,但降级
  • 错误时发被动错误标志(6 隐性,不破坏)
  • 帧间隔多等 8 个隐性(挂起传输,降优先级)
  • TEC/REC 96~127

4.5 总线关闭(Bus-Off)

  • 完全不通信(隔离,保护总线)
  • TEC ≥ 128(发送)或 TEC ≥ 255
  • 需恢复(见下节)
  • 功能安全关键状态

五、自动重发

5.1 自动重发机制

  • 帧发送失败(ACK错/被错误帧破坏)→ 控制器自动重发
  • 软件不感知(除非配置单次发送模式)
  • 重发直到成功或总线关闭

5.2 重发时机

  • 错误帧后,总线闲 + IFS(+ 被动状态多等 8 隐性)
  • 重发参与仲裁(可能被更高优先级抢占)

5.3 单次发送模式

  • 部分控制器支持(STM32 NART 位)
  • 发一次不重发,软件处理
  • 适用:实时性要求(超时丢弃)/ 测试

5.4 重发的问题

  • 高优先级帧持续错 → 重发占总线 → 低优先级饿死
  • 功能安全:重发次数限制(超限进安全状态)

六、总线关闭恢复

6.1 总线关闭状态

  • TEC ≥ 128 → 总线关闭
  • 节点完全不收发(隔离,避免持续错影响总线)
  • 控制器进入 Bus-Off 状态

6.2 自动恢复

  • 总线关闭后,检测到128 × 11 = 1408 个连续隐性位(约 11 帧时间)
  • 自动回到主动错误状态(TEC/REC 清 0)
  • 条件:总线有其他正常节点通信(产生隐性位)

6.3 软件恢复

  • 部分控制器需软件触发恢复(退出 Bus-Off)
  • STM32:清 ABOM 位 → 软件请求恢复
  • Linux:ip link set can0 up(重新启用)

6.4 恢复策略

策略说明
自动恢复(ABOM)检测 1408 隐性自动恢复,推荐
软件恢复软件检测 Bus-Off 后手动恢复
不恢复锁死(功能安全降级,需人工干预)

6.5 功能安全考量

  • 总线关闭 = 节点故障,可能安全风险
  • 恢复后要重新同步状态(应用层)
  • AEGIX:总线关闭超阈值 → 进安全状态(不无限恢复)

总线关闭恢复是 AEGIX 功能安全必考
功能安全芯片 CAN 节点,总线关闭是故障状态。恢复策略:自动恢复(ABOM) + 恢复次数限制 + 超限进安全状态。不能无限恢复(可能硬件故障,继续通信危险)。恢复后应用层重新同步状态。这是功能安全审查重点。对照 [[10-SPI错误处理与恢复]] 的端到端保护,CAN 的总线关闭是协议层保护,SPI 要软件实现。


七、错误中断与处理

7.1 错误中断源

中断触发
错误警告(EWGF)TEC/REC ≥ 96(进被动)
错误被动(EPVF)TEC/REC ≥ 128 或从被动回主动
总线关闭(BOFF)TEC ≥ 128(进 Bus-Off)
最后错误码(LECN)上次错误类型(位/CRC/格式/ACK/填充)

7.2 错误处理流程

voidcan_error_isr(void){uint32_tesr=CAN->ESR;if(esr&BOFF){// 总线关闭log_error("CAN Bus-Off");enter_safe_state();// 功能安全// 等自动恢复或软件恢复}if(esr&EPVF){// 错误被动log_warning("CAN Error Passive, TEC=%d REC=%d",(esr>>16)&0xFF,(esr>>24)&0xFF);}if(esr&EWGF){// 错误警告log_warning("CAN Error Warning");}uint8_tlec=(esr>>4)&0x7;switch(lec){case1:log_error("Stuff Error");break;case2:log_error("Form Error");break;case3:log_error("Ack Error");break;case4:log_error("Bit1 Error");break;case5:log_error("Bit0 Error");break;case6:log_error("CRC Error");break;}}

7.3 错误统计

  • Linux:ip -s link show can0看 RX/TX 错误统计
  • 实时监控错误计数器(TEC/REC)
  • 错误日志记录(功能安全可追溯)

八、关键问题 Q&A

Q1:CAN 五种错误检测分别什么时候触发?

A:

  • 位监控:发送方每发一位读回比对,不符(除仲裁区)
  • 位填充:接收方看到 6 连续同电平(应 5+填充)
  • CRC:接收方 CRC 不符
  • 格式:固定隐性位(CRC/ACK 界定符/EOF/IFS)出现显性
  • ACK:发送方 ACK 间隙读到隐性(无应答)

Q2:错误计数器怎么涨?为什么错+8 成功-1?

A:错+8,成功-1。设计意图:偶发错误快速恢复(1 次成功抵 1 次错),持续错误快速降级(8 次错进被动)。这样偶发噪声不致降级,持续故障快速隔离(被动→总线关闭)。

Q3:主动错误和被动错误有什么区别?

A:

  • 主动错误(TEC/REC<96):错误标志 6 显性,破坏当前帧(所有节点丢弃)
  • 被动错误(TEC/REC 96~127):错误标志 6 隐性,不破坏(其他节点可能正常接收),帧间多等 8 隐性(降优先级)
  • 被动错误是降级状态,减少对总线影响

Q4:总线关闭怎么恢复?

A:

  • 自动恢复(ABOM):检测 128×11=1408 连续隐性位,自动回主动错误(TEC/REC 清0)
  • 软件恢复:软件检测 Bus-Off,手动请求恢复(Linuxip link set can0 up)
  • 恢复条件:总线有其他正常节点(产生隐性位)
  • 功能安全:恢复次数限制,超限进安全状态

Q5:CAN 自动重发,什么时候停?

A:持续重发直到:① 成功;② 总线关闭(TEC≥128,停止)。没有重发次数限制(除非单次发送模式 NART)。高优先级帧持续错会占总线,低优先级饿死。功能安全要软件限制(超时丢弃/进安全状态)。

Q6:错误计数器怎么看?

A:

  • 裸机:读 CAN_ESR(STM32)的 TEC/REC 字段
  • Linux:ip -s link show can0看 RX/TX errors
  • 调试:逻辑分析仪抓错误帧,统计频率
  • 功能安全:实时监控,超阈值告警

九、实战案例

案例 1:总线关闭,节点失联

现象:某节点 TEC 飙到 200,总线关闭,完全不通信。

分析:节点波特率配错(和全网不一致),发的帧别人采错(CRC错),ACK错,TEC 持续涨到 ≥128,总线关闭。

解决:修正波特率(和全网一致),总线关闭恢复(ABOM 自动或软件重启)。

案例 2:错误被动,通信降级

现象:节点 TEC 100(被动错误),通信时断时续。

分析:节点偶发位定时错(采样点偏),部分帧 CRC 错,TEC 涨到 96+ 进被动。

解决:修正位定时(采样点 87.5%),TEC 降到 96 以下,回主动错误。

案例 3:ACK 错误,单节点自测

现象:单节点测试,发送报 ACK 错误,TEC 涨。

分析:单节点无其他节点应答(ACK 间隙无显性),ACK 错,TEC 涨到总线关闭。

解决:单节点测试开 Loopback 模式(自收自发 ACK),或加另一节点。

案例 4:EMI 导致位填充错误

现象:CAN 总线偶发位填充错误,错误帧频发。

分析:EMI 让位翻转,连续同电平被破坏,位填充规则违反。

解决:加共模扼流圈 + TVS,远离干扰源,双绞屏蔽。

案例 5:总线关闭无限恢复循环

现象:节点总线关闭,自动恢复,又快速总线关闭,循环。

分析:节点硬件故障(收发器坏),恢复后发的帧错,TEC 快速涨又总线关闭。

解决:限制恢复次数(3 次后锁死),进安全状态,人工干预。

案例 6:高优先级帧重发,低优先级饿死

现象:高优先级帧(0x001)持续 ACK 错(目标节点故障),重发占总线,低优先级饿死。

分析:自动重发无次数限制,高优先级持续错占总线。

解决:单次发送模式(NART)或软件超时丢弃,目标节点故障进安全状态。

案例 7:CRC 错误,采样点不一致

现象:部分帧 CRC 错误,错误帧破坏,通信不稳。

分析:某节点采样点 75%,全网 87.5%,采错数据,CRC 不符。

解决:统一采样点 87.5%,CRC 错消失。

案例 8:格式错误,EOF 被干扰

现象:帧末格式错误(EOF 应隐性,出现显性),重发。

分析:EMI 在 EOF 期间干扰,显性混入隐性区。

解决:加抗扰措施(共模扼流圈/TVS/双绞),EOF 错误减少。


十、本篇小结与速查

核心要点

  • CAN 五种错误检测:位监控/位填充/CRC/格式/ACK(硬件自动)
  • 错误帧:主动错误(6显性,破坏)/被动错误(6隐性)+ 8 隐性定界
  • 错误计数器:TEC(发送)/REC(接收),错+8 成功-1
  • 节点状态:主动错误(<96)/被动错误(96~127)/总线关闭(≥128)
  • 主动错误:正常通信,错误破坏当前帧;被动错误:降级,不破坏
  • 总线关闭:完全隔离(不收发),保护总线
  • 自动重发:帧错自动重发(无次数限制,除非 NART)
  • 总线关闭恢复:128×11=1408 隐性位自动恢复 / 软件恢复
  • 功能安全:恢复次数限制 + 超限进安全状态 + 恢复后重新同步
  • 错误中断:BOFF/EPVF/EWGF/LEC,实时监控

错误检测速查

错误检测方触发
位监控发送方发≠读(除仲裁)
位填充接收方6 连续同电平
CRC接收方CRC 不符
格式接收方定界符/EOF 显性
ACK发送方ACK 间隙隐性

状态机速查

状态TEC/REC行为
主动错误<96正常 + 6显性错误标志
被动错误96~127降级 + 6隐性错误标志
总线关闭≥128隔离,不通信

错误处理流程

  1. 检测错误(5 种)
  2. 发错误帧(主动/被动)
  3. 错误计数器更新(TEC/REC)
  4. 状态转移(主动→被动→总线关闭)
  5. 自动重发(除非总线关闭)
  6. 总线关闭恢复(1408 隐性 / 软件)
  7. 功能安全:超限进安全状态

功能安全 CAN 错误处理清单

  • 错误中断处理(BOFF/EPVF/EWGF)
  • 错误计数器监控
  • 总线关闭恢复策略(ABOM + 次数限制)
  • 恢复超限进安全状态
  • 恢复后应用层重新同步
  • 错误日志记录(可追溯)
  • 看门狗兜底

延伸阅读

  • [[04-CAN帧格式]] —— CRC/ACK/EOF 错误源
  • [[05-CAN仲裁与优先级]] —— 仲裁错乱触发错误
  • [[03-CAN位定时与同步]] —— 位定时错导致 CRC 错
  • [[10-CAN错误恢复与总线关闭]] —— 恢复深入
  • [[14-CAN排查手册与速查表]] —— 错误速查
  • [[10-SPI错误处理与恢复]] —— 对比 SPI 错误处理
  • [[10-I2C错误处理与恢复]] —— 对比 I2C 错误处理

参考资料

  • Bosch CAN Specification 2.0(错误处理章节)
  • ISO 11898-1(错误管理)
  • STM32 RM0090(CAN ESR/错误中断)
  • ISO 26262 功能安全(CAN 容错)

[[00-CAN技术系列总目录]] · 上一篇:[[05-CAN仲裁与优先级]] ·下一篇:[[07-CAN高层协议]]


✨ 感谢你的阅读 ✨

技术之路漫漫,分享是为了更好地交流。
如果本文的内容对你有启发,希望能得到你的支持:

👍 点赞|⭐ 收藏|👀 关注

如果你在调试过程中遇到了其他问题,
欢迎在评论区 💬留言,我们一起探讨。

关注我,一起交流底层开发的那些事儿!🚀


需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询