第2章:ISO 14229-1 UDS基础:UDS服务分类与SID详解

好,咱们接着聊。上一章我们把UDS的定位和基本概念捋了一遍。这一章,我带你深入看看UDS的核心——服务。

你想想看,诊断仪和ECU之间怎么对话?靠的就是这些服务。每个服务都有一个唯一的ID,我们叫它SID(Service Identifier)。ISO 14229-1把UDS服务分成了六大类。嗯,这就像工具箱里的不同分区,每个分区放不同功能的工具。

2.1 六大服务分类概览

我个人习惯把这六大类记成一张表,方便随时查阅。你看:

分类编号 分类名称 SID范围(典型) 一句话说明
1 诊断与通信管理 0x10 - 0x3E 管连接、管会话、管安全
2 数据传输 0x22 - 0x2E 读数据、写数据
3 存储数据传输 0x14 - 0x19 读写DTC、快照、扩展数据
4 输入输出控制 0x2F 强制控制执行器或传感器
5 远程激活 0x31 - 0x3D 远程启动程序、例程
6 上传/下载 0x34 - 0x37 刷写、数据传输

注意,这个分类不是随便分的。它背后有很强的逻辑。比如,你想读一个故障码,你得先建立诊断连接(诊断与通信管理),然后才能去读存储的数据(存储数据传输)。顺序不能乱。

核心要点:UDS的六大分类,本质上是把诊断任务按功能域切分。每个域的服务,解决一类特定问题。

2.2 诊断与通信管理服务(0x10 - 0x3E)

这个分类,说白了就是「握手」和「维持连接」的服务。我刚开始做诊断时,总觉得这些服务不重要,后来被坑过一次——有一次测试,ECU死活不响应诊断请求,查了半天,发现是会话没切过去。

这里有几个关键服务:

  • 0x10 诊断会话控制(DiagnosticSessionControl):切换ECU的工作模式。默认会话、编程会话、扩展会话。每个会话下,能用的服务不一样。
  • 0x11 ECU复位(ECUReset):让ECU重启。分硬复位、软复位、快速上电复位等。
  • 0x27 安全访问(SecurityAccess):解锁ECU的受保护功能。需要种子-密钥验证。
  • 0x3E 测试仪在线(TesterPresent):告诉ECU「我还活着」,防止会话超时。

举个例子,你想刷写ECU,必须先发0x10切换到编程会话,然后发0x27解锁,最后才能刷。少一步都不行。

我的经验:0x3E这个服务,很多工程师会忽略。我曾经遇到过,诊断仪发完请求后,ECU过几秒就自动退出了会话。原因就是没发TesterPresent。记住,这个服务要周期性发送,间隔一般不超过2秒。

2.3 数据传输服务(0x22 - 0x2E)

这个分类,是UDS里最常用的。你想想看,诊断仪最常干的事是什么?读数据、写数据。

  • 0x22 读取数据标识符(ReadDataByIdentifier):通过DID(Data Identifier)读取ECU内部数据。比如读车速、读电压、读VIN码。
  • 0x2E 写入数据标识符(WriteDataByIdentifier):通过DID写入数据。比如写VIN码、写配置参数。
  • 0x23 读取内存地址(ReadMemoryByAddress):直接读内存地址。这个比较底层,一般开发阶段用。

这里有个坑。0x22和0x2E的DID,每个OEM都有自己的定义。比如,大众的DID 0xF190可能是VIN,宝马的可能是另一个。所以,做诊断开发时,一定要拿到OEM的DID定义表。

注意:0x2E写入数据时,很多ECU要求先解锁(0x27)。否则会返回否定响应码0x33(securityAccessDenied)。我见过有人写VIN码时忘了这步,折腾了半天。

2.4 存储数据传输服务(0x14 - 0x19)

这个分类,专门管故障码(DTC)相关的数据。包括:

  • 0x14 清除诊断信息(ClearDiagnosticInformation):清除所有DTC和相关数据。
  • 0x19 读取诊断信息(ReadDTCInformation):读取DTC状态、快照数据、扩展数据等。

0x19这个服务,子功能特别多。比如:

  • 子功能0x01:返回DTC数量
  • 子功能0x02:返回DTC状态
  • 子功能0x03:返回所有DTC
  • 子功能0x04:返回快照数据
  • 子功能0x06:返回扩展数据

我个人建议,做诊断测试时,先把0x19的各个子功能都跑一遍。因为很多ECU的DTC管理逻辑,只有通过这个服务才能摸清楚。

2.5 输入输出控制服务(0x2F)

这个服务,只有一个:0x2F 输入输出控制(InputOutputControlByIdentifier)

它的作用是什么?强制控制ECU的某个输入或输出。比如,强制让某个继电器吸合,或者强制让某个传感器输出一个固定值。

这个服务在产线和售后维修中非常有用。比如,你想测试一个车门锁电机是否正常,直接发0x2F控制它动作,看它能不能正常开锁、关锁。

避坑指南:0x2F控制输出时,一定要小心。我曾经在测试中,用0x2F强制控制了一个风扇继电器,结果忘了恢复,风扇一直转,把电池耗光了。所以,控制完后,记得发一个「恢复默认值」的控制命令。

2.6 远程激活服务(0x31 - 0x3D)

这个分类,核心是0x31 例程控制(RoutineControl)

例程,就是ECU内部的一段预定义程序。你可以通过0x31来启动、停止或查询这个例程的执行结果。

比如,ECU里有一个「自学习」例程。你发0x31启动它,ECU就开始执行自学习。执行完后,你再发0x31查询结果。

0x31有三个子功能:

  • 0x01:启动例程
  • 0x02:停止例程
  • 0x03:查询例程结果

另外,0x3D 写入内存(WriteMemoryByAddress)也属于这个分类。它和0x2E类似,但更底层,直接写内存地址。

2.7 SID与子功能详解

每个UDS服务,都有一个SID。但很多服务还有子功能(SubFunction)。子功能用来区分同一个服务下的不同操作。

比如,0x19(读取DTC信息)有几十个子功能。0x31(例程控制)有3个子功能。

子功能在请求报文中的位置,通常是SID后面的第一个字节。比如:

请求:0x19 0x02 0xFF 0xFF 0xFF
解释:SID=0x19,子功能=0x02(返回DTC状态),后面是DTC掩码

这里要注意,子功能字节的最高位(bit 7)有特殊含义。如果bit 7=0,表示这个请求需要ECU发送响应。如果bit 7=1,表示不需要响应(抑制响应位)。

举个例子:

  • 0x19 0x02:需要响应
  • 0x19 0x82:抑制响应,ECU不回复

这个抑制响应位,在批量诊断时很有用。比如,你连续发多个请求,如果每个都要响应,总线负载会很高。抑制响应后,可以节省带宽。

我的习惯:开发阶段,我一般不用抑制响应位。因为我想看到每个请求的响应,方便调试。但到了产线测试,我会用抑制响应位,提高测试效率。

2.8 本章小结

这一章,我们聊了UDS的六大服务分类,以及每个分类下的核心服务。记住:

  • 诊断与通信管理:管连接、会话、安全
  • 数据传输:读写DID数据
  • 存储数据传输:读写DTC相关数据
  • 输入输出控制:强制控制执行器
  • 远程激活:启动例程、写内存
  • 上传/下载:刷写相关

下一章,我们会深入讲一个最常用的服务——0x22读取数据标识符。我会带你看看DID的定义、请求响应的格式,以及我在项目中踩过的坑。

嗯,今天就到这儿。你先把这六大类记熟,后面就好办了。