错误帧的作用

本文解析了CAN总线中错误帧的类型及其工作原理,包括主动错误帧和被动错误帧的区别,以及节点如何响应这些错误。介绍了不同错误状态下的节点行为,并通过形象的比喻帮助理解。

错误帧分为主动错误帧和被动错误帧

主动错误帧:6-12个显示标识位+8个隐形位

被动错误帧:6个隐形错误标识(可被其他在节点在显性位覆盖)+8个隐形位

实现原理

打破CAN总线位填充规则,从而导致接受数据节点产生错误

节点错误形式

主动错误状态:可以正常收发数据(主动、被动错误计数器均小于128),可以发送主动错误帧
被动错误状态:是节点本身受干扰或错误比较多时的工作模式,只能发送被动错误帧(主动、被动错误计数器其一在127、256之间),其实就是不允许它阻塞别的正常节点的通讯
总线关闭模式:节点错误很多时进入的模式(收或发错误计数器等于256),收发都被禁止。

主动报错和被动报错

1.主动报错站点:只要检查到错误,它立即"主动地"发出错标识 
所谓"出错标识",它本身就是一个"错误的位序列"(连续的6个显性位,不满足CAN协议的"最多5个连续的同性位"要求),目的是"主动地"告诉大家:即使你们 没有发现"刚才我已发现"的错误,现在我"以身作则"出错啦!你们该看到这个错误了吧!

2.被动报错站点:如果检查到错误,它只能干瞪眼"被动地"等别人(主动报错站点)报错,等待的时候它可不能去动总线,直到识别出由主动报错站点发出的"错误的位序列",它才松了一口气:有人正式报错了!然后他就可以去竞争总线,该干啥干啥

3.出错标识本身没有什么优先级的问题.

4.对于通过竞争得到总线使用权的发送站点来说,它在一边发一边听,有可能:

(a).它自己就发现错误,它就干脆哗啦哗啦,乱发一气(连续的发六个同性位). 就象你小时候在幼儿园练习写字,写错一个笔画你自己就不耐烦了,在纸上哗啦哗啦,乱画一气.目的就是告诉别人(别的站点),出错了!

(b).它自己没有发现错误,但作为主动报错的接收站点发现了错误(比如因为线路长,干扰大引起的错误),这个发现错误的站点就会立即哗啦哗啦往总线上乱发一气(连续的发六个显性位),就象你小时候在幼儿园练习写字, 写错一个笔画你自己没发现,可老师(主动报错站点)发现了就不耐烦了, 在你的纸上哗啦哗啦,乱画一气.目的就是你自己以及告诉别人(发送站点和别的站点),出错了!

(c).它自己没有发现错误,但作为被动报错的接收站点发现了错误(比如因为线路长,干扰大引起的错误),这个发现错误的站点只能慢慢的等待,等待别的主动报错站点报错,如果别的主动报错站点没发现错误,那就继续等,一直等到该发ACK的时候不给发送站发这个显性的ACK信号,当然了其他站点可能会发这个ACK,那说明其他站点没有发生错误,没办法,别人能通信, 你不能!然后积攒到一定的时候,你就脱离总线吧!再继续等待一段时间, 脱胎换骨,重新回到总线上(这个时候错误记录都清0了,你肯定是主动报错站了).就象你小时候在幼儿园练习写字,写错一个笔画你自己没发现, 别的同学(被动报错站点)发现了但他不能说,嘿嘿(乱说话,老师要打屁股的),他就只能等,等老师来发现你的错误(等待主动报错站点报错),或者老师没眼力,那就等到收作业的时候,不收你的(不发ACK),不过老师可能主动来收的(给你发ACK),那你可没办法,继续等吧,等到你也当老师了(脱胎换骨了),.........


在 **CAN(Controller Area Network)通信** 中,**错误帧(Error Frame)** 是一种特殊的帧类型,用于通知总线上其他节点:某个节点检测到了通信错误。它是 CAN 协议中实现高可靠性和自检能力的关键机制之一。 --- ## ✅ 什么是错误帧? 根据 **ISO 11898-1** 标准定义,当任何 CAN 控制器在接收或发送过程中检测到错误时,它会立即发出一个 **错误帧**,以中断当前传输,防止错误数据被接受。 ### 🔹 错误帧作用: - 检测并报告通信异常 - 强制所有节点丢弃当前帧 - 触发重传机制(对消息透明) - 维护总线一致性与可靠性 --- ## 📦 错误帧的结构 错误帧由两部分组成: | 部分 | 内容 | 长度 | |------|------|-------| | **错误标志(Error Flag)** | 6~12 位显性电平 | 6~12 bit | | **错误界定符(Error Delimiter)** | 8 位隐性电平 | 8 bit | ### 1. **错误标志(Error Flag)** - **主动错误标志(Active Error Flag)**:6 个连续显性位(0),由处于“主动错误”状态的节点发送。 - **被动错误标志(Passive Error Flag)**:由处于“被动错误”状态的节点发送,不主动驱动总线,而是监测其他节点的错误标志。 > 注意:错误标志会破坏正常的位填充规则(每5个相同位后必须变),从而触发所有节点的错误检测。 ### 2. **错误界定符(Error Delimiter)** - 8 个连续隐性位(1) - 用于将错误帧与后续帧隔离开 ```text [ 错误标志 (6~12 bit 显性) ] [ 错误界定符 (8 bit 隐性) ] ``` --- ## ⚠️ 常见触发错误帧的原因 CAN 节点通过以下几种方式检测错误,一旦发现即发送错误帧: | 错误类型 | 描述 | |--------|------| | **位错误(Bit Error)** | 发送显性位但读回隐性位(仅发送器可检测) | | **填充错误(Stuff Error)** | 连续出现 6 个相同位(违反位填充规则) | | **CRC 错误(CRC Error)** | 接收方计算的 CRC 与帧中不符 | | **格式错误(Form Error)** | 帧中固定格式字段出现非法位(如 ACK delimiter 应为隐性却为显性) | | **应答错误(Ack Error)** | 发送方未检测到至少一个显性 ACK 位 | --- ## 💡 实际示例:Python 使用 `python-can` 捕获错误帧 虽然大多数 CAN 接口硬件会过滤掉错误帧,但某些设备(如 PCAN-USB Pro、Kvaser Leaf Pro)支持“错误帧捕获”模式。 ```python import can # 启用错误帧监听(需硬件支持) bus = can.interface.Bus(bustype='pcan', channel='PCAN_USBBUS1', state=can.bus.BusState.ERROR_ACTIVE) print("Listening for error frames...") try: while True: msg = bus.recv(timeout=1.0) if msg is None: continue # 判断是否为错误帧 if msg.is_error_frame: print(f"🚨 Error Frame Detected!") print(f" Arbitration ID: 0x{msg.arbitration_id:X}") print(f" DLC: {msg.dlc} (represents error type)") print(f" Data: {msg.data.hex()}") else: print(f"✅ Normal Frame: ID=0x{msg.arbitration_id:X}, Data={msg.data.hex()}") except KeyboardInterrupt: print("Stopped.") finally: bus.shutdown() ``` > 🔍 注:并非所有 CAN 适配器都能上报错误帧。建议使用支持“error frame pass-through”的专业设备。 --- ## 🧠 错误帧背后的 CAN 错误处理机制 CAN 节点内部维护两个计数器: | 计数器 | 名称 | 作用 | |--------|------|------| | **TEC** | Transmit Error Counter | 发送错误次数 | | **REC** | Receive Error Counter | 接收错误次数 | ### 节点状态转换规则: | TEC / REC 值 | 状态 | 行为 | |-------------|------|------| | TEC < 128, REC < 128 | 主动错误(Error Active) | 可主动发送错误帧 | | TEC ≥ 128 或 REC ≥ 128 | 被动错误(Error Passive) | 不能主动发送错误帧,只能标记 | | TEC > 255 | 总线关闭(Bus Off) | 完全断开,需重启恢复 | > 示例:监控 TEC/REC(需通过底层 API,如 PEAK PCAN 的 DLL) ```python # 使用 pypcan 获取错误计数(伪代码) from pypcan import PCANBasic, PCAN_USBBUS1, TPCANStatus, TPCANMsg status = TPCANStatus() msg = TPCANMsg() # 查询错误状态 result = PCANBasic.ReadErrorCounters(PCAN_USBBUS1, status) if result == PCAN_ERROR_OK: print(f"TEC: {result.Transmit}, REC: {result.Receive}") ``` --- ## 🛠️ 如何测试错误帧? ### 测试场景设计: | 场景 | 方法 | 预期结果 | |------|------|----------| | **人为制造填充错误** | 发送含 6 个连续相同位的数据 | 其他节点发送错误帧 | | **模拟 ACK 缺失** | 断开一个接收节点 | 发送方产生 Ack Error 并重传 | | **短路测试** | CAN_H 与地短接一段时间 | 多个节点进入错误状态甚至 Bus Off | | **高负载干扰** | 满载总线 + EMC 干扰 | 观察错误帧频率和恢复能力 | --- ## ✅ 总结:错误帧的核心要点 | 项目 | 内容 | |------|------| | 类型 | 特殊控制帧,非用户数据 | | 结构 | 错误标志 + 错误界定符 | | 触发条件 | 位错误、填充错误、CRC 错误等 | | 发送者 | 检测到错误的节点(主动错误状态下) | | 影响 | 中断当前帧,触发重传 | | 监控难度 | 需要专用硬件才能捕获 | | 安全意义 | 实现故障隔离与系统鲁棒性 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值