第3章:UDS诊断协议(ISO 14229):UDS服务分类与常用SID
好,咱们今天聊聊UDS。说实话,UDS(统一诊断服务)是TBOX开发里绕不开的坎。你想想看,车上的ECU(电子控制单元)出了故障,总得有个标准化的沟通方式吧?UDS就是干这个的。ISO 14229这个标准,说白了就是给汽车电子系统定了一套“问诊”的规矩。
我个人习惯把UDS理解成医生和病人的对话。TBOX是医生,ECU是病人。医生问“你哪里不舒服?”,病人回答“我第3个传感器读数异常”。这套对话,就是UDS服务。
3.1 UDS服务分类
UDS服务按功能分成六大类。我刚开始接触时觉得分类挺多,后来发现其实就几个核心方向。咱们一个个看。
| 功能组 | 服务ID范围 | 典型用途 |
|---|---|---|
| 诊断与通信管理 | 0x10 - 0x3E | 会话控制、安全访问、ECU复位 |
| 数据传输 | 0x22 - 0x2E | 读取/写入数据、动态定义标识符 |
| 存储数据传输 | 0x14 - 0x19 | 读取故障码、清除故障码 |
| 输入输出控制 | 0x2F | 强制控制执行器、模拟输入信号 |
| 远程激活 | 0x31 | 启动例程、刷写程序 |
| 上传/下载 | 0x34 - 0x37 | 固件升级、数据块传输 |
嗯,这里要注意:实际项目中,数据传输和存储数据传输这两类用得最频繁。我在TBOX项目里,80%的诊断交互都集中在读故障码和读写数据上。
3.2 常用SID详解
SID(服务标识符)就是UDS服务的“身份证号”。每个服务对应一个字节的ID。下面这几个,是我认为必须掌握的。
3.2.1 0x10 - 诊断会话控制
这个服务用来切换ECU的工作模式。ECU默认是“默认会话”,功能受限。你要做诊断,得先切换到“扩展会话”或“编程会话”。
关键点:不同会话下,ECU允许执行的服务不同。比如刷写固件必须在编程会话下进行。
我记得有一次,客户反馈TBOX连不上ECU。排查了半天,发现是TBOX发送了诊断请求,但ECU还在默认会话里,压根不响应。后来我们在初始化流程里加了一步会话切换,问题就解决了。
3.2.2 0x22 - 按标识符读取数据
这个服务用来读取ECU内部的数据。比如读取电池电压、车速、软件版本号等。你给一个DID(数据标识符),ECU就返回对应的值。
// 读取ECU软件版本号(DID = 0xF190)
请求:22 F1 90
响应:62 F1 90 01 02 03 04 // 版本号:01.02.03.04
实际项目中,我建议把常用的DID整理成表格。比如TBOX需要读取的VIN码(车辆识别号)、硬件版本、序列号等,提前定义好,测试时直接查表。
3.2.3 0x2E - 按标识符写入数据
和0x22相反,这个服务用来写入数据。比如配置ECU的参数、写入VIN码等。注意,写入操作通常需要先进行安全访问(0x27服务)。
警告:写入操作有风险!我曾经在测试时,不小心写错了某个配置参数,导致ECU功能异常。后来花了半天才恢复。所以,写入前一定要做校验,最好有“写前读”的机制。
3.2.4 0x31 - 例程控制
这个服务用来启动、停止ECU内部的例程。例程可以理解成一段预定义的程序。比如启动自检、执行校准、擦除Flash等。
举个例子,TBOX刷写固件时,会先通过0x31启动“擦除例程”,把旧的固件擦掉,然后再通过0x34(请求下载)写入新固件。
// 启动擦除例程(例程ID = 0xFF00)
请求:31 01 FF 00
响应:71 01 FF 00 // 例程执行成功
我个人习惯把0x31服务叫做“万能钥匙”。很多ECU的特殊功能,比如进入工厂模式、恢复出厂设置,都是通过例程实现的。
3.2.5 0x19 - 读取故障码信息
这个服务是诊断的重头戏。它用来读取ECU存储的故障码(DTC)。故障码告诉你哪个部件出了问题。
0x19有很多子功能,常用的有:
- 0x01:读取当前故障码数量
- 0x02:读取所有故障码
- 0x0A:读取最近发生的故障码
我记得有一次,客户的车在高速上突然报“发动机故障灯”。我们用TBOX读取故障码,发现是“氧传感器加热电路故障”。后来检查发现是线束插头松了。你看,没有UDS诊断,这种问题排查起来就像大海捞针。
3.3 避坑指南
做UDS诊断测试,有几个坑我踩过,分享给你:
- 超时处理:ECU响应有超时限制。默认是50ms。如果TBOX发送请求后没收到响应,要重试。我曾经遇到过ECU在忙时直接不响应,TBOX傻等,导致诊断链路卡死。
- 安全访问:很多写入操作需要先通过0x27服务进行安全解锁。解锁算法通常是种子-密钥模式。测试时一定要确认算法实现正确,否则会一直报“安全访问拒绝”。
- 会话保持:ECU在扩展会话下,如果一段时间没有收到诊断请求,会自动切回默认会话。这个时间通常是5秒。所以,长时间诊断时要定时发送“Tester Present”(0x3E)服务保持会话。
小技巧:写自动化测试脚本时,我习惯把UDS服务封装成函数。比如ReadDataByIdentifier(did)、WriteDataByIdentifier(did, data)。这样测试用例写起来就像搭积木,清晰又高效。
3.4 总结
UDS诊断协议,说白了就是一套标准化的“问诊”流程。你掌握了0x10、0x22、0x2E、0x31、0x19这几个核心服务,就能覆盖TBOX开发中90%的诊断需求。剩下的,遇到具体问题再查标准文档就行。
嗯,这一章就到这里。下一章咱们聊聊UDS的传输层——ISO 15765,看看诊断数据是怎么在CAN总线上跑的。