第3章 UDS服务分类:诊断服务分类、功能单元、服务ID(SID)概览、请求与响应机制
好,咱们进入第三章。这一章可以说是UDS诊断的骨架。你想想看,一个诊断协议,如果没有清晰的服务分类,那调试起来就是一团乱麻。我个人习惯,拿到一个ECU的诊断规范,第一件事就是翻到服务列表那一页,看看它支持哪些SID。
3.1 诊断服务分类:到底分几类?
UDS(ISO 14229)把诊断服务分成了三大类。为什么这么分?说白了,就是按照「你想对ECU做什么」来划分的。
- 诊断和通信管理类:这类服务负责建立会话、控制诊断通信、做安全校验。比如0x10(诊断会话控制)、0x27(安全访问)、0x3E(Tester Present)。
- 数据传输类:这类服务负责读写数据。比如0x22(读取数据)、0x2E(写入数据)、0x23(读取内存)。
- 存储数据传输类:这类服务负责操作ECU内部的故障码(DTC)。比如0x14(清除诊断信息)、0x19(读取DTC信息)。
嗯,这里要注意,还有一类叫「输入输出控制类」,比如0x2F(通过ID控制输入输出)。有些文档把它单独列出来,有些归到数据传输类里。我个人觉得,只要你能理解它的用途就行,不必纠结分类名称。
3.2 功能单元:把服务打包成「功能包」
功能单元这个概念,很多刚接触UDS的工程师容易忽略。它其实是一个逻辑分组。举个例子,0x19服务(读取DTC信息)下面有28个子功能,比如按状态掩码读取、按严重等级读取等等。这些子功能就组成了一个「DTC功能单元」。
我在项目中遇到过,有些OEM会自定义功能单元。比如把0x22(读取数据)和0x2E(写入数据)打包成一个「数据管理功能单元」。这样做的好处是,你在做诊断需求分析时,可以按功能单元来分配任务,而不是一个一个SID去抠。
核心要点:功能单元不是协议强制要求的,但它是OEM做诊断规范时常用的组织方式。你调试时,如果看到某个服务返回了NRC 0x12(子功能不支持),先别急着怀疑ECU,看看是不是功能单元没对上。
3.3 服务ID(SID)概览:一张表搞定
SID是每个服务的身份证。一个字节,范围0x00到0xFF。但UDS只用了其中一部分。我建议你记住下面这张表,调试时能省不少时间。
| SID(十六进制) | 服务名称 | 分类 |
|---|---|---|
| 0x10 | 诊断会话控制 | 诊断和通信管理 |
| 0x11 | ECU复位 | 诊断和通信管理 |
| 0x14 | 清除诊断信息 | 存储数据传输 |
| 0x19 | 读取DTC信息 | 存储数据传输 |
| 0x22 | 通过ID读取数据 | 数据传输 |
| 0x27 | 安全访问 | 诊断和通信管理 |
| 0x2E | 通过ID写入数据 | 数据传输 |
| 0x2F | 通过ID控制输入输出 | 输入输出控制 |
| 0x3E | Tester Present | 诊断和通信管理 |
为什么是这些SID?因为它们是UDS协议里最常用的。我曾经调试过一个项目,ECU只支持0x10、0x22、0x2E和0x3E,其他一概不支持。嗯,这种情况在低端ECU上很常见。
3.4 请求与响应机制:一问一答,但也有例外
UDS的通信模式,说白了就是「请求-响应」。Tester发一个请求,ECU回一个响应。但这里有几个细节,我踩过坑,得跟你聊聊。
3.4.1 请求格式
一个标准的UDS请求,格式是这样的:
[SID] + [子功能/数据参数] + [数据]
举个例子,读取数据(0x22)的请求:
22 F1 90
这里0x22是SID,0xF190是数据ID(DID)。
3.4.2 响应格式
响应分两种:肯定响应和否定响应。
- 肯定响应:格式是
[SID + 0x40] + [数据]。比如上面的请求,响应是62 F1 90 [数据字节]。 - 否定响应:格式是
0x7F + [SID] + [NRC]。比如7F 22 31,表示请求超出范围。
个人经验:调试时,我最喜欢看否定响应。因为NRC能直接告诉你ECU为什么拒绝你的请求。我曾经遇到一个ECU,每次发0x22都返回0x7F 22 11(服务不支持),查了半天才发现是会话模式不对——ECU只在扩展会话下才支持0x22。
3.4.3 多帧传输
如果数据量太大,一帧CAN报文装不下怎么办?UDS支持多帧传输。比如读取一大段内存(0x23),数据可能超过8个字节。这时候就需要用ISO 15765-2的传输层协议来分包。
嗯,这里要注意,多帧传输的流控制(FC帧)很容易出问题。我建议你在调试时,先用CAN工具抓一下总线,看看是不是有帧丢失或者流控超时。
3.4.4 无响应的情况
有些服务是不需要响应的。比如0x3E(Tester Present),ECU收到后不会回任何东西。为什么?因为0x3E的作用就是告诉ECU「我还活着」,如果ECU每次都回响应,总线负载就上去了。
避坑指南:我曾经在调试时,发现ECU对0x3E没有响应,以为ECU死机了。后来查规范才知道,0x3E的响应是可选的。所以,如果你看到某个请求没有响应,先查一下规范,别急着怀疑硬件。
3.5 小结
这一章我们聊了UDS服务的分类、功能单元、SID概览,还有请求与响应机制。说白了,UDS就是一套「你问它答」的规则。你只要记住SID、子功能、NRC这三要素,调试起来就不会慌。
下一章,我们会深入0x10服务——诊断会话控制。这是所有诊断通信的起点,也是我调试时最常打交道的一个服务。