4. UDS协议栈架构
上一章我们把UDS的会话控制和安全访问讲透了。这一章咱们继续往下走,聊聊实际开发中最常用的几个服务——读数据、写数据、读DTC、清DTC。
说实话,这几个服务你几乎每天都会打交道。不管是产线刷写、售后诊断,还是研发阶段的调试,都离不开它们。我个人习惯把这几个服务分成两组:数据访问组(0x22、0x2A、0x2E)和故障管理组(0x19、0x14)。
4.1 读取数据(0x22)—— 最常用的诊断服务
0x22服务,说白了就是让诊断仪读取ECU内部的数据。这些数据通过数据标识符(DID)来索引。每个DID对应一个特定的数据对象,比如ECU序列号、软件版本、当前车速、电池电压等等。
请求格式很简单:
请求:0x22 + DID(2字节)
响应:0x62 + DID + 数据内容
举个例子,读取ECU序列号(假设DID = 0xF190):
请求:22 F1 90
响应:62 F1 90 41 42 43 44 45 46 47 48
("ABCDEFGH"的ASCII码)
0x22服务支持一次请求读取多个DID。但要注意,每个DID的数据长度必须固定,否则ECU无法正确解析响应。我建议在诊断规范里明确每个DID的数据类型和长度,避免后期扯皮。
4.2 读取数据周期(0x2A)—— 自动上报的利器
0x2A服务是0x22的升级版。它让ECU按照指定的周期,自动上报DID数据。这在实时监控场景下特别有用,比如标定工程师想看某个信号的变化趋势。
0x2A有三个子功能:
| 子功能 | 含义 | 说明 |
|---|---|---|
| 0x01 | 开始周期上报 | 指定DID和上报周期(单位ms) |
| 0x02 | 停止周期上报 | 停止指定DID的周期上报 |
| 0x03 | 读取当前周期上报配置 | 返回当前正在上报的DID列表 |
请求格式:
开始上报:2A 01 + DID + 周期(2字节,单位ms)
停止上报:2A 02 + DID
读取配置:2A 03
另外,0x2A服务通常只在扩展会话(0x03)下可用。这是出于安全考虑,防止正常运行时被误触发。
4.3 写入数据(0x2E)—— 改参数、刷配置
0x2E服务用来向ECU写入数据。它和0x22是一对儿,一个读一个写。请求格式:
请求:2E + DID + 数据内容
响应:6E + DID + 数据内容(回显)
举个例子,写入ECU的VIN码(假设DID = 0xF190):
请求:2E F1 90 31 32 33 34 35 36 37 38
("12345678"的ASCII码)
响应:6E F1 90 31 32 33 34 35 36 37 38
我个人习惯把0x2E服务分为两类:
- 运行时参数: 比如调整某个控制算法的系数,修改后立即生效,但掉电丢失。
- 持久化参数: 比如VIN码、配置字,修改后需要写入非易失性存储器(EEPROM/Flash),掉电不丢失。
对于持久化参数,写入次数有限制(Flash有擦写寿命)。我在一个量产项目里就遇到过,产线反复写入VIN码导致Flash提前报废。后来我们加了一个保护机制:只有VIN码为空时才允许写入,否则返回NRC 0x72(一般编程失败)。
4.4 读取DTC信息(0x19)—— 故障诊断的核心
0x19服务是UDS里最复杂的服务之一。它用来读取ECU中存储的故障码(DTC)及其相关信息。0x19有28个子功能,但常用的就几个:
| 子功能 | 含义 | 常用场景 |
|---|---|---|
| 0x01 | 读取DTC数量(按状态掩码) | 快速了解当前有多少故障 |
| 0x02 | 读取DTC列表(按状态掩码) | 获取所有故障码 |
| 0x03 | 读取DTC快照数据 | 故障发生时的环境数据 |
| 0x04 | 读取DTC扩展数据 | 故障发生次数、老化计数器等 |
| 0x06 | 读取DTC(按组号) | 按故障类型分组查询 |
| 0x0A | 读取所有DTC(支持多个状态掩码) | 一次性获取所有故障信息 |
状态掩码(Status Mask)是0x19服务的核心概念。每个DTC都有一个1字节的状态字节,各位含义如下:
| 位 | 含义 | 说明 |
|---|---|---|
| Bit 0 | 测试失败 | 当前诊断测试失败 |
| Bit 1 | 本次操作周期测试失败 | 当前驾驶循环内测试失败 |
| Bit 2 | 已确认的故障 | 故障被确认并存储 |
| Bit 3 | 未确认的故障 | 故障尚未被确认 |
| Bit 4 | 测试完成 | 诊断测试已执行完毕 |
| Bit 5 | 本次操作周期测试未完成 | 当前驾驶循环内测试未完成 |
| Bit 6 | 警告指示灯请求 | 请求点亮故障灯(MIL) |
| Bit 7 | 待处理故障 | 故障待处理 |
快照数据(Snapshot Data)是0x19的另一个重要功能。它记录了故障发生时的环境数据,比如车速、发动机转速、冷却液温度等。这些数据对故障分析非常有帮助。
4.5 清除DTC信息(0x14)—— 一键恢复出厂
0x14服务用来清除ECU中存储的DTC信息。请求格式很简单:
请求:14 + 组号(1字节)
响应:54 + 组号
组号(Group Number)用来指定要清除哪些DTC:
| 组号 | 含义 |
|---|---|
| 0x00 | 清除所有DTC |
| 0x01 - 0xFE | 清除指定组的DTC(由OEM定义) |
| 0xFF | 清除所有DTC(包括历史记录) |
我在一个量产项目里遇到过一个问题:产线在刷写完成后,会执行0x14服务清除所有DTC。但有个ECU在清除后,立即报了一个新的故障码。后来发现是诊断测试的时序问题——清除DTC后,某些测试条件还不满足,导致误报。解决方案是在清除DTC后,延迟一段时间再启动诊断测试。
4.6 本章小结
这一章我们聊了五个核心服务:
- 0x22(读取数据): 通过DID读取ECU内部数据,支持多DID读取。
- 0x2A(读取数据周期): 让ECU按周期自动上报数据,适合实时监控。
- 0x2E(写入数据): 向ECU写入数据,通常需要安全访问。
- 0x19(读取DTC信息): 读取故障码及其状态、快照、扩展数据。
- 0x14(清除DTC信息): 清除ECU中的故障码信息。