第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总线上跑的。