2、CAN总线协议详解:CAN 2.0A/B标准、数据帧结构、远程帧与错误帧

好,咱们进入正题。这一章我打算把CAN总线协议的核心骨架给你拆开揉碎了讲。说实话,很多工程师干了三五年,对CAN的理解还停留在“能发数据就行”的层面。但你要做OTA升级,就必须深入到帧结构里去,否则你连“为什么升级包要分包发送”都搞不明白。

2.1 CAN 2.0A与2.0B标准:别小看这11位和29位

CAN总线最早是博世公司搞出来的。2.0A是标准版,2.0B是扩展版。它们最大的区别,说白了就是ID的长度。

  • CAN 2.0A(标准帧):仲裁段有11位标识符。报文ID范围是0x000到0x7FF,总共2048个。
  • CAN 2.0B(扩展帧):仲裁段有29位标识符。报文ID范围大得多,0x00000000到0x1FFFFFFF。

我在做第一个车载项目时,就踩过这个坑。当时用的MCU只支持2.0A,结果客户要求用29位ID做诊断。没办法,只能换芯片。所以你现在选型,我建议直接上支持2.0B的控制器,别省那几毛钱。

核心区别速览

特性CAN 2.0ACAN 2.0B
标识符长度11位29位
最大ID数量2048约5.36亿
帧格式标准帧标准帧 + 扩展帧
兼容性2.0B节点可收2.0A2.0A节点收不到扩展帧

你想想看,OTA升级时,一个ECU可能要同时处理诊断、网络管理、应用报文。如果ID不够用,29位扩展帧就是你的救命稻草。

2.2 数据帧结构:OTA升级包就是靠它传的

数据帧是CAN总线最常用的帧类型。OTA升级时,你那些几百KB的bin文件,就是被切成一段段塞进数据帧里的。

一个标准数据帧长这样:

SOF | 11位ID | RTR | IDE | r0 | DLC | 0~8字节数据 | CRC | ACK | EOF

我来拆开讲几个关键字段:

  • SOF(起始帧):1个显性位。告诉总线“我要开始说话了”。
  • 仲裁段(ID + RTR):ID决定了优先级。数字越小,优先级越高。OTA升级时,我习惯把升级相关报文设成高优先级,比如ID=0x100,防止被其他报文堵死。
  • 控制段(IDE + r0 + DLC):DLC告诉别人我这帧带了多少数据。注意,DLC最大是8,所以一帧最多传8字节。这就是为什么OTA要分包——你没法一帧传完整个固件。
  • 数据段:0到8字节。升级数据就放这里。我见过有人把DLC设成8但只用了3个字节,浪费带宽。建议按实际数据长度设置DLC。
  • CRC段:15位CRC校验。如果算出来不对,接收方会发错误帧。
  • ACK段:发送方发隐性位,接收方拉成显性位表示“我收到了”。

我的经验:OTA升级时,建议在数据段里加一个序列号。比如字节0是包序号,字节1-7是数据。这样接收方可以检查有没有丢包。我曾经遇到过总线负载高导致丢帧,全靠序列号才发现问题。

2.3 远程帧:你问,别人答

远程帧(Remote Frame)的作用很简单:请求数据。发送方发一个远程帧,告诉目标节点“把你的数据发给我”。

远程帧和数据帧长得几乎一样,唯一的区别是RTR位:

  • 数据帧:RTR = 0(显性)
  • 远程帧:RTR = 1(隐性)

远程帧没有数据段。它的DLC表示你想要多少字节。比如你发一个DLC=8的远程帧,对方就应该回一个8字节的数据帧。

说实话,远程帧在OTA升级中用得不多。但我在做UDS诊断时经常用它。比如请求ECU的软件版本号,发一个远程帧,ECU就会把版本信息回过来。嗯,这里要注意:远程帧的ID必须和目标数据帧的ID一致,否则对不上。

避坑指南:我曾经在一个项目里发现,某些低端CAN控制器对远程帧支持不好。发出去后对方没反应,或者回的数据不对。如果你要用远程帧,建议先查一下芯片手册,或者干脆用数据帧模拟请求-响应模式。

2.4 错误帧:总线上的“警报器”

错误帧是CAN总线自我保护的机制。当节点检测到错误时,它会主动发送错误帧,通知其他节点“刚才那帧有问题,别用了”。

错误帧由两部分组成:

  1. 错误标志:6个连续显性位(主动错误)或6个连续隐性位(被动错误)。
  2. 错误界定符:8个隐性位。

CAN总线有5种错误类型:

错误类型说明常见原因
位错误发送方监控总线,发现电平不一致总线短路、多节点同时发送
填充错误连续6个相同电平位填充规则被破坏
CRC错误接收方算出的CRC和发送方不一致数据被干扰、波特率不匹配
形式错误固定格式位出现错误电平总线干扰、节点故障
ACK错误发送方没收到显性ACK没有节点接收、总线断开

OTA升级时,我最怕的就是CRC错误。因为升级包数据量大,一旦总线干扰严重,错误帧会频繁出现,导致重传,升级时间成倍增加。我建议你在OTA前先做一次总线质量测试,看看错误帧率。如果超过1%,就得考虑降低波特率或者加中继器了。

关键点:错误帧不是用来“报错”的,而是用来“纠错”的。发送方发现错误后会自动重发。所以CAN总线在物理层上就保证了可靠性。但重发会占用带宽,OTA升级时要注意这一点。

2.5 总结:这些帧在OTA中怎么用?

好了,四种帧都讲完了。我帮你串一下:

  • 数据帧:传升级数据。一帧8字节,分包发送。
  • 远程帧:请求ECU状态。比如“你准备好升级了吗?”
  • 错误帧:总线出问题时自动触发。你要监控它,判断总线质量。
  • 过载帧:这个我没细讲,因为它用得少。简单说就是“我忙不过来,你慢点发”。

下一章我会讲CAN的位时序和同步机制。你想想看,为什么CAN总线能抗干扰?为什么波特率能设到1Mbps?这些都得从位时序说起。到时候见。