4、通信协议基础:CAN总线简介、UDS协议概述、诊断会话控制

各位同学,咱们今天聊聊Bootloader通信的“地基”。

做ECU升级,说白了就是通过一根线,把新程序灌进芯片里。这根线怎么传数据?传的数据长什么样?谁说了算?这就是CAN总线和UDS协议要解决的问题。我个人习惯把这一节叫做“翻译官与高速公路”——CAN是路,UDS是交通规则。

4.1 CAN总线:汽车上的“神经”

CAN总线,全称Controller Area Network。1980年代由Bosch发明,初衷就是为了让车上各个ECU能互相说话。你想想看,一个现代汽车有几十个ECU,如果每个ECU都拉一根独立的线到仪表盘,那线束比发动机还重。CAN总线用两根线(CAN_H和CAN_L)就把所有节点串起来了。

CAN总线的几个关键点:

  • 差分信号:两根线电压差决定逻辑0或1。抗干扰能力强,适合汽车这种电磁环境恶劣的地方。我在项目中遇到过,有一次CAN通信偶尔丢帧,查了半天发现是CAN_H线被一根电源线压住了,屏蔽层破损。嗯,从此我对线束布线格外敏感。
  • 多主通信:任何节点都可以随时发消息,没有“老大”一说。谁抢到总线谁说话。
  • 仲裁机制:如果两个节点同时发,ID小的优先。ID就是消息的“身份证号”。
  • 帧结构:标准帧11位ID,扩展帧29位ID。Bootloader里常用标准帧,因为够用。

CAN报文长什么样?

一个典型的CAN数据帧包含:SOF(起始位)、仲裁场(ID + RTR)、控制场(DLC,数据长度)、数据场(0~8字节)、CRC场、ACK场、EOF(结束位)。

注意:数据场最多8个字节。这是CAN协议的限制。所以UDS协议里,超过8字节的数据要分包发送。

避坑指南:我曾经在一个项目里,把CAN总线波特率设成了500kbps,但某个供应商的ECU只支持250kbps。结果就是,我的诊断仪能连上,但刷写时总超时。后来发现是波特率不匹配。所以,做Bootloader之前,先确认好整车网络的波特率,这是基本功。

4.2 UDS协议:诊断世界的“普通话”

CAN总线只是物理层和数据链路层。它只管把0和1从A点搬到B点。但搬过去的是什么?怎么解释?这就需要UDS协议了。

UDS,全称Unified Diagnostic Services,统一诊断服务。它是ISO 14229标准定义的。说白了,就是汽车行业里ECU和诊断仪之间沟通的“普通话”。不管你是博世、大陆还是电装的ECU,只要支持UDS,诊断仪就能用同一套指令跟它对话。

UDS的核心概念:

  • 服务ID(SID):每条指令都有一个ID。比如0x10是诊断会话控制,0x22是读取数据,0x2E是写入数据,0x34是请求下载。
  • 请求与响应:诊断仪发请求(Request),ECU回响应(Response)。响应分两种:肯定响应(SID + 0x40)和否定响应(0x7F + SID + NRC)。
  • NRC(否定响应码):比如0x12(子功能不支持)、0x22(条件不满足)、0x31(请求超出范围)。

举个例子:

诊断仪想读取ECU的VIN码(车辆识别号)。

请求:02 22 F1 90

  • 02:数据长度(2字节)
  • 22:服务ID(读取数据)
  • F1 90:数据标识符(VIN码的ID)

响应:06 62 F1 90 4C 46 56 33 30 31

  • 06:响应长度
  • 62:肯定响应(22 + 0x40)
  • F1 90:数据标识符
  • 4C 46 56 33 30 31:ASCII码,对应“LFV301”

个人经验:UDS协议里,我最常用的是0x10、0x22、0x2E、0x34、0x36、0x37这几个服务。尤其是0x10(诊断会话控制),它是所有刷写流程的“大门”。你进不了门,后面什么都干不了。

4.3 诊断会话控制:刷写的“门禁系统”

ECU不是谁都能随便刷的。它有不同的“会话模式”,就像门禁卡有不同的权限。

UDS协议定义了三种标准会话:

  • 默认会话(Default Session):上电后的初始状态。只能做基本的诊断,比如读故障码。不能刷写。
  • 编程会话(Programming Session):刷写专用的会话。只有在这个会话下,才能执行0x34(请求下载)、0x36(传输数据)等刷写服务。
  • 扩展诊断会话(Extended Diagnostic Session):比默认会话权限高,可以执行一些特殊功能,比如写入配置参数、执行例程。但通常不能直接刷写。

会话切换流程:

  1. 诊断仪发送0x10 02(请求进入编程会话)。
  2. ECU检查条件是否满足(比如车速为0、点火开关ON、没有DTC激活等)。
  3. 如果满足,ECU回复肯定响应(0x50 02)。
  4. 如果不满足,ECU回复否定响应(0x7F 10 NRC)。常见的NRC是0x22(条件不满足)。

注意:编程会话有一个“会话超时”机制。ECU进入编程会话后,如果一段时间内(通常是5秒)没有收到任何有效的诊断请求,它会自动跳回默认会话。这是为了防止刷写过程中通信中断导致ECU“卡死”在编程模式。

我曾经在一个项目中,刷写脚本里忘了发“保持激活”的报文(0x3E 0x80),结果刷到一半ECU跳回默认会话了。嗯,那次刷写失败了,还得重新来。从那以后,我写脚本时都会在循环里加上0x3E的定时发送。

会话控制的关键点总结:

会话类型 SID + 子功能 典型用途 是否支持刷写
默认会话 0x10 0x01 上电初始、基本诊断
编程会话 0x10 0x02 Bootloader刷写
扩展诊断会话 0x10 0x03 配置、标定、例程 通常否

好了,这一节的内容就这些。CAN总线是路,UDS协议是交通规则,诊断会话控制就是门禁卡。三者缺一不可。下一节我们会深入讲刷写流程中的“请求下载”和“传输数据”,到时候你会更清楚这些基础概念是怎么串起来的。