深入解析CAN2.0协议:帧类型与错误处理机制
1. 从汽车聊起为什么需要CAN总线如果你拆开过一辆现代汽车的车门可能会被里面密密麻麻的线束吓一跳。在早期汽车上的每个功能比如车窗升降、后视镜调节、座椅加热都需要一组独立的电线连接到控制开关。功能越多线束就越复杂、越重成本也越高更别提排查故障时那种“剪不断理还乱”的痛苦了。为了解决这个难题工程师们想出了一个聪明的办法让这些电子控制单元ECU像在一个微信群里聊天一样通过一根共享的“数据总线”来通信。这条总线就是控制器局域网也就是我们常说的CAN总线。它诞生于上世纪80年代由德国博世公司率先提出初衷就是为了简化汽车内部的布线。你可以把它想象成一条所有设备都能使用的“公共发言通道”谁有话要说就按规则上去讲其他设备都能听到。那么这条“公共通道”的发言规则是什么呢这就是CAN协议。我们今天要深入聊的CAN 2.0协议就是这套规则中最经典、应用最广泛的版本。它定义了在这个“群聊”里消息以什么样的格式发送帧类型以及当有人说错话或者网络出现干扰时如何快速发现并纠正错误处理。正是这套严谨的规则保证了即使在发动机舱这样电磁环境复杂、干扰强烈的“恶劣聊天环境”下刹车、气囊、发动机控制等关键信息也能可靠、实时地传递不会出错。理解了帧和错误处理你就抓住了CAN总线可靠性的核心。2. CAN 2.0的“语言”五种核心帧类型详解在CAN的“群聊”里信息不是随便喊一嗓子就行的必须包装成符合格式的“消息包”这就是“帧”。CAN 2.0协议主要定义了五种帧它们各司其职共同维持着总线通信的秩序。咱们一个一个来拆解我会用更生活化的例子帮你理解。2.1 数据帧承载信息的“快递包裹”数据帧是总线上的主角负责携带实际的数据内容比如发动机转速、车速、水温等。它就像一个精心包装的快递包裹结构非常清晰。一个完整的数据帧由7个部分段构成咱们来模拟发送一条“车速80km/h”的消息帧起始一个显性位逻辑0。就像开会时敲一下木槌大喊一声“安静我要发言了”通知总线上所有节点“注意一帧数据要开始传输了”仲裁段这是帧的“身份证”和“优先权凭证”。它包含本帧的标识符。标准格式是11位CAN 2.0A扩展格式是29位CAN 2.0B。这个ID不仅用来标识消息内容比如0x100代表车速更重要的是决定了消息的优先级。ID数值越小优先级越高。当两个节点同时想发言时它们会从仲裁段的第一位开始一边发一边听。如果自己发的是隐性位逻辑1却听到总线是显性位逻辑0就说明有更高优先级的消息在发送自己立刻闭嘴退出竞争。这个过程叫“无损仲裁”保证了高优先级消息总能先发出去不会像以太网那样发生碰撞导致大家都发不成。控制段共6位其中4位是数据长度码用来告诉接收方“我这个包裹里有几个字节的数据。”CAN规定一帧最多带8个字节的数据非常精简适合传输实时性要求高的控制指令。另外两位是保留位通常发显性位。数据段这就是真正的“货物”长度是0到8个字节。我们的“车速80”就会被编码放在这里。虽然只有8字节但对于大多数控制指令来说绰绰有余。CRC段15位的循环冗余校验码 1位CRC界定符。发送方会根据前面帧起始、仲裁段、控制段、数据段的内容计算出一个CRC值放在这里。接收方收到后用同样的算法再算一遍。如果算出来的结果和收到的不一样就知道数据在传输过程中可能被干扰了立刻就会报错。这就像快递员在包裹单上写了一个基于货物内容生成的特殊校验码你收到货后自己按规则也算一个对不上就说明货物可能被调包了。ACK段确认段包含ACK槽和ACK界定符。这个设计非常巧妙发送方在这一段会发出两个隐性位。而所有正确收到这一帧的接收节点注意不是目标节点是所有听到的节点都会在ACK槽这个位置覆盖性地输出一个显性位。于是发送方原本发出的隐性位就被“改写”成了显性位。发送方只要在ACK槽检测到显性位就知道“至少有一个节点完好地收到了我的消息”。这是一种高效的广播确认机制。帧结束由7个连续的隐性位组成表示本帧数据干干净净地结束了。2.2 遥控帧主动“催更”的请求遥控帧可以理解为“请求数据帧”。当一个节点需要某些数据时它不会傻等而是主动发一个遥控帧去“索要”。它的结构非常像数据帧但有两大关键区别RTR位为隐性在仲裁段后有一个远程传输请求位。数据帧的RTR位是显性而遥控帧的RTR位是隐性。这是硬件层面区分两者的标志。没有数据段遥控帧只“点名要什么”不“携带数据”。它的仲裁段ID指明了它想要哪个数据例如ID 0x100的车速数据。它的数据长度码表示它希望收到的对应数据帧的数据长度。举个例子仪表盘需要显示车速但车速信号是由发动机ECU发出的。仪表盘就可以定期向总线发送一个ID为0x100的遥控帧。总线上所有节点都看到了这个请求拥有车速数据的发动机ECU识别到这个ID是给自己的请求就会立刻组织一个ID为0x100的数据帧携带当前车速值发送到总线上。这样仪表盘就拿到了最新数据。遥控帧实现了数据的“按需提供”减少了不必要的广播优化了总线负载。2.3 错误帧紧急叫停的“警报”这是CAN协议可靠性的核心体现。任何节点在任何时候只要检测到通信出现异常都有权利立即发出一个错误帧强行中断当前帧的传输要求发送方重发。错误帧像是一个尖锐的警报结构简单粗暴错误标志由6个相同的位组成。这里分为两种情况主动错误标志6个连续显性位。当一个节点处于“主动错误状态”通常错误计数较低时它发出这个标志。这6个显性位会破坏正常帧的位填充规则后面会讲从而让总线上所有节点都意识到出错了。被动错误标志6个连续隐性位。当一个节点因频繁出错而进入“被动错误状态”时它只能发出这个标志。它不能主动打断别人的发送只能等着别人发现错误。如果此时总线是空闲的它的错误标志才能发出去。错误界定符8个连续隐性位。在错误标志之后提供一段“冷静期”让总线恢复到空闲状态为错误帧结束后的重传做准备。我遇到过一种情况在实验室用双绞线模拟CAN总线如果线接得比较长且没有加终端电阻就容易因为信号反射产生位错误。一旦某个位在传输中畸变接收节点会立刻抛出一个错误帧发送节点感知到后会在总线空闲时自动重发刚才那一帧。这个过程非常快对于上层应用来说可能只是通信延迟略微增加了一点点但数据最终是正确的。这就是错误帧的“纠错”作用。2.4 过载帧接收方的“暂停”手势过载帧和错误帧结构很像6个显性位8个隐性位但意义不同。它是由接收节点发出的意思是“我这边处理不过来了你慢点发”。可能的原因有接收节点的内部缓冲区快满了。接收节点在处理更高优先级的任务暂时无法处理新来的数据帧。当过载帧发出后总线会进入一段“过载间隔”所有发送节点都会暂停发送给接收方喘息的时间。这就像开会时你说得太快记录员举手示意“请讲慢一点我跟不上了”。在实际车载网络中由于ECU处理能力都很强过载帧相对比较少见但协议提供了这个机制来应对极端情况。2.5 帧间隔消息之间的“呼吸”帧间隔是帧与帧之间的必要分隔符由至少3个隐性位间隔段和一段可变长度的总线空闲时间组成。它的作用有两个分隔清晰地区分开前一帧和后一帧。同步总线空闲期让所有节点的内部时钟有机会重新同步为下一次准确采样位电平做准备。如果没有这个“呼吸”间隙所有的帧连在一起接收方就无法准确判断一帧从哪里开始、到哪里结束。协议规定错误帧和过载帧之后不会紧跟帧间隔因为它们本身就是异常处理的一部分后面会直接跟重传或等待。3. CAN的“免疫系统”五位一体错误检测与处理机制CAN总线被誉为最可靠的汽车总线之一其核心就在于它强大且多层次的错误检测机制。它不像我们日常的网络通信主要依赖软件重传而是在硬件和协议底层就构建了五道防线。任何一道防线检测到问题都会触发错误处理流程。3.1 五种错误类型及其检测原理位错误发送节点一边往外发送位电平一边会回读总线上的电平。如果发现自己发送的位和总线上实际出现的位不一致比如自己发了显性0却读回隐性1就会触发位错误。例外情况在仲裁段期间这种不一致不算错误而是正常的“仲裁失败”节点会礼貌退出发送。在ACK槽期间发送方发隐性位却读到显性位这反而是好消息说明有节点成功接收了。填充错误这是CAN协议一个非常巧妙的物理层检错设计。为了防止长时间出现相同的电平信号导致接收方时钟失步CAN协议规定在帧起始到CRC段之间如果连续出现5个相同的位无论是5个0还是5个1发送方必须自动插入一个反相的电平位这叫“位填充”。接收方在接收时则会自动删除这个填充位。如果接收方在删除填充位后发现连续6个位都是相同的电平它就断定“这违反了填充规则传输肯定出错了”这就是填充错误。它能有效检测由突发干扰引起的多位错误。CRC错误这是最经典的校验方式。发送方计算CRC接收方独立计算并比对。如果CRC校验码不匹配说明从帧起始到数据段的内容在传输中发生了改变。CRC校验的覆盖范围很广检错能力极强。格式错误接收方会检查帧结构中那些有固定格式的部分。例如帧结束的7个位必须是隐性位如果检测到显性位就报格式错误。再比如CRC界定符、ACK界定符、错误界定符等位置都必须是固定电平不符合就算格式错误。这相当于检查“语法”是否正确。ACK错误发送方在ACK槽如果没有检测到任何显性位即没有任何一个节点给出确认它就会认为自己发送失败触发ACK错误。这通常意味着要么所有接收节点都出错了要么物理链路断了。3.2 错误处理与节点状态迁移仅仅检测错误还不够CAN协议定义了一套完整的错误处理与节点状态机来管理总线上的“问题节点”。每个节点内部都有两个计数器发送错误计数器和接收错误计数器。错误主动状态这是节点的默认健康状态。当错误计数较低时节点处于此状态。它可以正常收发报文并且在检测到错误时有权发出强大的主动错误标志6个显性位去强行打断当前传输要求重发。错误被动状态如果一个节点频繁出错发送或接收错误计数器超过127它就会进入“错误被动”状态。作为一种“惩罚”或“隔离”机制它虽然还能参与通信但能力受限它发出错误帧时只能发送被动错误标志6个隐性位。这个标志无法主动打断正在进行的正常传输只能等总线空闲时才能发出影响力大减。它在发送一帧后必须等待额外的“延迟传送”时间8个隐性位才能发送下一帧相当于被“限流”了。总线关闭状态这是最严重的状态。当发送错误计数器超过255时节点认为自己造成了严重干扰会彻底关闭自己的CAN收发器与总线物理断开连接。它无法再发送或接收任何帧只能通过等待或外部干预来尝试恢复。这个机制至关重要它防止了一个彻底故障的节点“死机”后持续向总线发送乱码从而“拖垮”整个网络的灾难性情况。我在调试一个自制CAN节点板卡时就遇到过因为程序bug导致疯狂发送错误帧很快这个节点就进入了总线关闭状态而总线上其他设备完全不受影响通信照常。这充分体现了CAN的“鲁棒性”。4. 深入细节位时序、同步与网络稳定性要让多个独立的节点在一条总线上和谐通信光有帧格式和错误检测还不够它们必须在时间上保持同步用同样的“节奏”去解读每一位信号。这就是位时序要解决的问题。4.1 位时序的构成把一位时间切成四段CAN总线的一个位时间并不是简单的一个时钟周期而是被精细地划分成四个不重叠的段每个段由整数个最小时间单位时间份额构成。同步段固定为1个Tq。用于同步总线上的跳变沿。理想情况下位的边沿就发生在这里。传播时间段长度可编程1-8个Tq。这个段是用来补偿信号在物理总线上传输延迟的。信号从发送节点到最远的接收节点需要时间这段延迟必须被考虑进去。相位缓冲段1长度可编程1-8个Tq。可以将其终点理解为采样点的位置。接收节点就是在这个时间点对总线电平进行采样并确定该位是0还是1。相位缓冲段2长度可编程2-8个Tq。用于补偿时钟频率的微小偏差为下一次同步提供缓冲。配置位时序本质上就是在配置这几个段的Tq数量。一个关键的经验是采样点通常建议设置在一位时间的75%到90%之间。设置得太靠前信号可能还没稳定设置得太靠后留给处理的时间又太短。4.2 同步机制硬同步与再同步节点如何保持同步呢靠的是检测总线上的帧起始下降沿从隐性1到显性0的跳变。硬同步只在帧起始时发生。当检测到帧起始的下降沿时无论当前处于位时间的哪个阶段都会强制将当前位时间的计时器重置从同步段重新开始。这相当于在每一帧开始时把所有节点的“手表”强行归零对齐。再同步在帧的传输过程中如果后续的跳变沿没有出现在预期的同步段内由于节点间晶振的微小差异就会触发再同步。根据跳变沿是提前还是滞后相位缓冲段1会被拉长或相位缓冲段2会被缩短从而微调下一个位时间的长度让采样点逐渐对齐到正确位置。正是这套同步机制使得CAN节点不需要昂贵的高精度晶振用普通的陶瓷谐振器就能实现稳定的长距离通信。在实际配置CAN控制器比如常用的SJA1000或MCU内置CAN模块时我们需要根据总线波特率和芯片时钟频率仔细计算并设置这些时间段的值这是让CAN网络稳定跑起来的第一步也是调试通信问题时常需要检查的地方。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2411972.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!