4、UDS诊断服务详解(上):读取数据(0x22)、读取故障码(0x19)、写入数据(0x2E)、例程控制(0x31)
各位工程师朋友,今天我们聊聊UDS诊断服务里最常用的四个服务。说实话,这四兄弟在项目里出现的频率极高,你几乎每天都会跟它们打交道。我个人习惯把这四个服务称为「诊断四件套」——读数据、读故障码、写数据、跑例程。
嗯,咱们一个一个来拆解。
4.1 读取数据(0x22)—— 诊断的「眼睛」
0x22服务,说白了就是让ECU把内部数据吐出来给你看。你想知道车速?水温?电池电压?统统用这个服务去拿。
报文结构长这样:
请求:22 + DID(2字节) + 可选子字节
响应:62 + DID + 数据字节
举个例子,读取发动机转速(假设DID = 0x010C):
发送:22 01 0C
回复:62 01 0C 0F A0 → 转速 = 0x0FA0 = 4000 rpm
这里有个坑要注意——NRC 0x31(请求超出范围)。如果你发的DID在当前会话模式下不支持,ECU就会甩这个错误回来。比如有些DID只能在扩展会话(0x03)下读取,你在默认会话(0x01)下发,肯定吃闭门羹。
4.2 读取故障码(0x19)—— 诊断的「侦探」
0x19服务,用来读取ECU里存储的故障码。这个服务比0x22复杂不少,因为它有14个子功能。不过别慌,实际项目里常用的就那几个。
常用子功能一览:
| 子功能 | 含义 | 我常用的场景 |
|---|---|---|
| 0x01 | 读取故障码数量 | 快速判断ECU有没有报故障 |
| 0x02 | 读取故障码(按状态掩码) | 最常用,筛选当前激活的故障 |
| 0x0A | 读取所有故障码 | 全量导出,用于下线检测 |
| 0x0E | 读取故障码快照 | 分析故障发生时的环境数据 |
举个例子,读取当前所有激活的故障码(状态掩码 = 0x09):
发送:19 02 09
回复:59 02 01 01 00 11 22 33 → 1个故障码,DTC = 0x112233
我个人习惯用0x0A子功能做全量导出,然后用脚本解析。这样效率高,不容易漏数据。
4.3 写入数据(0x2E)—— 诊断的「手」
0x2E服务,就是往ECU里写数据。比如标定参数、配置信息、清除学习值等等。
报文结构:
请求:2E + DID(2字节) + 数据字节
响应:6E + DID + 数据字节
举个例子,写入VIN码(假设DID = 0xF190):
发送:2E F1 90 4C 53 56 38 30 30 30 30 31 32 33 34 35 36 37
回复:6E F1 90 4C 53 56 38 30 30 30 30 31 32 33 34 35 36 37
嗯,这里要注意——写入的数据长度必须和DID定义的长度一致。多一个字节或少一个字节,ECU都会返回NRC 0x13(报文长度错误)。我遇到过最离谱的一次,是有人把VIN码写成了18个字节,但DID定义的是17个字节,结果ECU直接锁死了写入功能,最后只能重新刷写固件才恢复。
4.4 例程控制(0x31)—— 诊断的「手术刀」
0x31服务,用来执行ECU内部的一段程序。比如自学习、传感器校准、执行器测试等等。这个服务有三个子功能:
| 子功能 | 含义 | 典型应用 |
|---|---|---|
| 0x01 | 启动例程 | 开始执行某个功能 |
| 0x02 | 停止例程 | 中断正在执行的例程 |
| 0x03 | 查询例程结果 | 获取执行状态或结果数据 |
举个例子,启动一个「节气门自学习」例程(假设RID = 0x0201):
发送:31 01 02 01
回复:71 01 02 01 00 → 例程启动成功
另外,有些例程是「一次性」的,启动后就不能再启动了,直到ECU重新上电。比如某些传感器的校准例程。如果你连续发两次启动请求,第二次就会收到NRC 0x22(条件不满足)。
4.5 四个服务的对比与选择
最后,我做个简单的对比,帮你快速决策:
| 服务 | 用途 | 需要安全访问? | 常见NRC |
|---|---|---|---|
| 0x22 | 读取数据 | 通常不需要 | 0x31(DID不支持) |
| 0x19 | 读取故障码 | 不需要 | 0x12(子功能不支持) |
| 0x2E | 写入数据 | 通常需要 | 0x13(长度错误)、0x31(DID不支持) |
| 0x31 | 执行例程 | 通常需要 | 0x22(条件不满足)、0x31(RID不支持) |
说白了,这四个服务覆盖了诊断开发中80%以上的需求。你只要把这四个服务吃透了,日常的测试工作基本就能应付自如。下一章我们继续聊剩下的几个服务——0x27安全访问、0x28通信控制、0x3E待机握手,这些都是诊断链路里的「守门员」角色。
好,今天就到这里。有什么问题,欢迎在群里交流。