第3章:UDS协议基础(ISO 14229-1)

好,咱们进入UDS协议的核心部分。说实话,很多刚入行的工程师觉得UDS就是一堆十六进制数,背下来就行了。但我个人习惯是——先搞懂它为什么这么设计,再去记那些SID。

UDS的全称是Unified Diagnostic Services,统一诊断服务。它定义了一套标准化的“对话规则”,让ECU和诊断仪能互相理解。你想想看,没有这套规则,每个ECU厂家都自己定义一套指令,那维修站得准备多少种诊断仪?

3.1 服务标识符(SID)分类

SID,Service Identifier,服务标识符。说白了就是一个字节的命令码。比如0x10代表“我要切换会话”,0x22代表“我要读数据”。

ISO 14229-1把SID分成了六大类,我整理了一张表,你一看就明白:

类别 SID范围 典型服务 说明
诊断和通信管理 0x10 ~ 0x3E 0x10(诊断会话控制)、0x3E(待机握手)、0x11(ECU复位) 管理诊断会话的生命周期
数据传输 0x22 ~ 0x2E 0x22(读取数据)、0x2E(写入数据) 读写DID(数据标识符)
存储数据传输 0x14 ~ 0x19 0x14(清除诊断信息)、0x19(读取DTC) 处理故障码
输入输出控制 0x2F 0x2F(输入输出控制) 强制控制执行器或传感器
远程激活 0x31 0x31(例程控制) 启动/停止ECU内部例程
上传/下载 0x34 ~ 0x37 0x34(请求下载)、0x36(传输数据) 刷写固件
重点提醒: 每个SID的请求和响应格式是固定的。比如0x22请求是“SID + DID”,响应是“SID+0x40 + DID + 数据”。这个0x40偏移量,我刚开始总是记混,后来发现规律——响应SID = 请求SID + 0x40。

3.2 诊断会话控制(0x10 / 0x3E)

0x10服务,DiagnosticSessionControl。它的作用就是切换ECU的工作模式。

ECU平时在跑正常功能,你总不能随便发个诊断指令它就停了吧?所以UDS定义了三种标准会话:

  • 默认会话(0x01): 上电后的初始状态。只允许读DTC、读VIN等基础操作。安全访问、刷写都不行。
  • 编程会话(0x02): 用于刷写固件。这个会话下,ECU会关闭一些通信,保证刷写不被打断。
  • 扩展会话(0x03): 用于更复杂的诊断,比如读写数据、执行例程。但刷写还是不行。

我在项目中遇到过一个问题:某ECU在扩展会话下发了0x2E写数据,结果ECU没响应。查了半天才发现——这个ECU的设计是写数据必须在编程会话下才能做。嗯,这里要注意,不同OEM对会话权限的定义可能不一样。

再说说0x3E,TesterPresent,待机握手。它的作用就一个——告诉ECU“我还活着,别退出诊断会话”。

ECU有个超时定时器,一般是5秒。如果5秒内没收到任何诊断请求,它就自动退回默认会话。所以诊断仪需要每隔一段时间发一个0x3E,保持会话活跃。

我的习惯: 0x3E的发送间隔设为2~3秒。太频繁浪费总线,太接近5秒又容易超时。我曾经见过一个测试脚本,间隔设成了4.9秒,结果网络一波动就超时,排查了好久才发现是这个问题。

3.3 安全访问(0x27)

0x27服务,SecurityAccess。说白了就是“解锁”。

为什么需要解锁?你想想看,如果任何人都能通过诊断仪改写ECU的数据,那车辆的安全性就完全失控了。所以UDS设计了一套“种子-密钥”机制。

流程是这样的:

  1. 诊断仪发0x27 + 请求种子(比如0x01表示请求种子)
  2. ECU返回种子(一串随机数,比如4个字节)
  3. 诊断仪用算法计算密钥,发0x27 + 发送密钥(比如0x02) + 密钥数据
  4. ECU验证密钥,正确则解锁成功
// 伪代码示例:种子-密钥交互
// 请求种子
Tx: 02 27 01        // 请求种子,安全级别0x01
Rx: 06 67 01 12 34 56 78  // 响应:种子为 0x12345678

// 发送密钥(假设算法是种子+0x01020304)
Tx: 06 27 02 13 35 57 79   // 密钥 = 0x12345678 + 0x01020304 = 0x13355779
Rx: 02 67 02              // 解锁成功
避坑指南: 我曾经遇到一个ECU,连续3次密钥错误后直接锁死,必须断电重启才能恢复。所以测试时一定要控制好重试次数。另外,有些ECU的种子是动态变化的,同一个种子不会出现两次,这是为了防止重放攻击。

安全级别通常有多个。0x01/0x02是一级,0x03/0x04是二级。一级可能只允许读数据,二级才允许写数据或刷写。具体怎么分,看OEM的设计。

3.4 ECU复位(0x11)

0x11服务,ECUReset。这个简单,就是让ECU重启。

复位类型有三种:

  • 硬复位(0x01): 模拟断电再上电。ECU所有RAM数据丢失,重新初始化。
  • 软复位(0x02): 类似看门狗复位。不一定会清空RAM,取决于ECU设计。
  • 快速上电复位(0x03): 某些OEM自定义的,用于快速恢复通信。

复位后ECU会做什么?它会发一个响应,然后立即重启。所以诊断仪必须在收到响应后,等待ECU重新上线。这个等待时间,不同ECU差别很大,从几十毫秒到几秒都有。

实战经验: 我测试过一个网关ECU,复位后需要3秒才能重新响应诊断请求。但测试用例里只等了1秒,结果后续的0x10会话切换全部失败。后来我加了一个“等待ECU上线”的循环,最多等5秒,每100ms发一次0x3E试探,直到收到响应为止。

另外,复位操作会清除一些临时数据,比如DTC的状态。所以如果你在做DTC测试,复位后记得重新读取DTC状态,看看是不是被清掉了。

好了,这一章的内容就这些。0x10、0x3E、0x27、0x11这四个服务,是UDS诊断的基础中的基础。你想想看,没有会话控制,诊断没法开始;没有安全访问,数据没法保护;没有复位,ECU出问题了都没法恢复。下一章咱们聊数据传输服务,0x22和0x2E,那才是真正读写数据的核心。