汽车诊断基础:UDS协议概述、诊断会话控制、安全访问、故障码读取与清除等核心服务
UDS(Unified Diagnostic Services,统一诊断服务)是ISO 14229标准定义的一套应用层诊断协议,它规范了诊断仪(Tester)与ECU(电子控制单元)之间的通信规则。在DoIP(Diagnostic over Internet Protocol,基于以太网的诊断)体系中,UDS作为应用层协议承载于TCP/UDP之上,是诊断仪开发工程师必须掌握的核心知识。本章将围绕UDS协议的核心服务展开,重点讲解诊断会话控制(0x10)、安全访问(0x27)、故障码读取(0x19)与清除(0x14)等关键服务的实现原理、报文格式、时序要求及工程实践中的常见问题。
UDS协议概述与DoIP中的定位
UDS协议定义了一套标准化的诊断服务,每个服务由一个服务ID(SID,Service ID)唯一标识。在DoIP诊断中,UDS报文被封装在DoIP协议的数据字段中,通过TCP端口13400(或UDP)传输。诊断仪发送请求报文(Request),ECU返回响应报文(Response),响应分为肯定响应(Positive Response)和否定响应(Negative Response)。肯定响应的格式为[SID+0x40] + 数据参数;否定响应的格式为[0x7F] + [SID] + [NRC(Negative Response Code,否定响应码)]。
UDS协议的核心设计思想是“服务-子功能-参数”三层结构。例如,0x10服务(诊断会话控制)的子功能包括0x01(默认会话)、0x02(编程会话)、0x03(扩展会话)等。每个子功能对应ECU不同的运行模式,不同模式下允许执行的服务集合不同。例如,在默认会话下通常只能执行读取类服务,而编程会话下才能执行Flash下载相关服务。
诊断会话控制(0x10)
诊断会话控制服务用于切换ECU的诊断会话模式。ECU上电后默认进入默认会话(Default Session),在该模式下仅允许执行基础诊断服务(如读取VIN码、读取DTC信息等)。当需要执行写入类操作(如Flash编程、参数配置)时,必须切换到编程会话(Programming Session)或扩展会话(Extended Session)。
请求报文格式:0x10 + SubFunction,其中SubFunction为0x01(默认)、0x02(编程)、0x03(扩展)。肯定响应格式:0x50 + SubFunction + P2* + P2*_max,其中P2*为ECU响应时间参数(单位毫秒),告知诊断仪当前会话下的默认响应时间和扩展响应时间。
会话切换的时序要求非常严格。诊断仪发送0x10请求后,ECU在P2时间内返回响应。如果诊断仪在P2时间内未收到响应,应等待P2*_max时间;若仍无响应,则需重发请求或进行超时处理。在实际DoIP开发中,建议将P2*和P2*_max参数动态解析并用于后续请求的超时控制。
| 子功能 | 会话名称 | 典型用途 | 允许的服务示例 |
|---|---|---|---|
| 0x01 | 默认会话 | 上电初始状态 | 0x10、0x19、0x22(读取数据) |
| 0x02 | 编程会话 | Bootloader下载 | 0x10、0x27、0x34(请求下载)、0x36(传输数据) |
| 0x03 | 扩展会话 | 高级诊断/标定 | 0x10、0x27、0x2E(写入数据)、0x14 |
安全访问(0x27)
安全访问服务用于保护ECU中的敏感数据或操作,防止未授权访问。其原理是:诊断仪发送0x27请求种子(Seed),ECU返回一个随机种子;诊断仪使用特定算法计算密钥(Key),再发送0x27请求密钥;ECU验证密钥正确后解锁安全级别。安全访问通常分为多个级别(如Level 1用于Flash编程,Level 2用于参数写入),每个级别对应不同的种子-密钥算法。
请求报文格式:0x27 + SubFunction + [Seed/Key]。子功能为奇数时表示请求种子(如0x01、0x03、0x05),偶数时表示发送密钥(如0x02、0x04、0x06)。肯定响应格式:0x67 + SubFunction + Seed/Key。否定响应常见NRC包括0x35(无效密钥)、0x36(尝试次数超限)、0x37(延时未到)。
安全访问的工程实现要点:
- 种子长度:通常为4字节或8字节,具体长度由ECU厂商定义。
- 密钥算法:常见算法包括CRC16、AES-128、自定义查表法。算法必须与ECU端完全一致。
- 延时机制:ECU在连续失败后(通常3次)会进入延时锁定状态(如10秒内禁止再次尝试)。诊断仪应实现失败计数和延时等待逻辑。
- 会话关联:安全解锁状态通常与会话绑定,切换会话后需重新解锁。
27 01请求种子,ECU返回67 01 1A 2B 3C 4D(种子为0x1A2B3C4D)。诊断仪使用厂商提供的算法计算密钥为0x5E6F7A8B,发送27 02 5E 6F 7A 8B。ECU验证通过后返回67 02。若密钥错误,ECU返回7F 27 35,诊断仪需等待延时后重试。
故障码读取(0x19)与清除(0x14)
故障码(DTC,Diagnostic Trouble Code)是ECU自诊断功能的输出结果。UDS协议中,0x19服务用于读取DTC信息,0x14服务用于清除DTC。0x19服务支持多种子功能,最常用的是0x02(按状态掩码读取DTC)和0x04(读取快照信息)。DTC状态掩码是一个字节,每一位代表一种状态(如bit0=测试失败,bit1=当前故障,bit2=历史故障等)。
0x19请求报文格式:0x19 + SubFunction + [参数]。例如,读取所有当前故障:19 02 09(0x09表示当前故障状态位)。肯定响应格式:0x59 + SubFunction + DTC数量 + [DTC编号 + 状态掩码]...。0x14请求报文格式:0x14 + 0xFF 0xFF 0xFF(清除所有DTC),肯定响应为0x54。
故障码读取的工程实践要点:
- 状态掩码设计:诊断仪应支持按不同状态组合查询DTC,如“当前故障”和“历史故障”分别查询。
- 多帧响应处理:当DTC数量较多时,0x19响应可能超过单帧长度,诊断仪需支持ISO-TP多帧重组(在DoIP中通常直接使用TCP流,但需注意TCP分段)。
- 清除DTC的时序:清除DTC前通常需要安全解锁,且清除操作会同时清除冻结帧和扩展数据。清除后建议重新读取确认DTC状态已更新。
| 服务 | SID | 典型子功能 | 常见NRC | 工程注意事项 |
|---|---|---|---|---|
| 读取DTC信息 | 0x19 | 0x01(按编号)、0x02(按状态)、0x04(快照) | 0x31(请求超出范围)、0x22(条件不满足) | 注意DTC编号格式(3字节),状态掩码位定义 |
| 清除DTC | 0x14 | 无(固定参数0xFFFFFF) | 0x72(一般编程失败)、0x33(安全访问被拒绝) | 清除前需安全解锁,清除后需重新读取确认 |
案例拆解:DoIP诊断仪读取并清除DTC的完整流程
以下是一个典型的DoIP诊断仪操作案例,展示从建立连接到清除DTC的完整流程。
背景与约束:某OEM的ECU支持DoIP诊断,诊断仪需通过以太网连接车辆网关,网关再路由到目标ECU。ECU在默认会话下允许读取DTC,但清除DTC需要切换到扩展会话并完成安全访问Level 1。
操作步骤:
- 建立DoIP连接:诊断仪发送DoIP车辆识别请求(VIN),网关返回车辆信息,诊断仪建立TCP连接。
- 读取DTC:发送
19 02 09,ECU返回59 02 01 01 02 03 09(表示1个DTC,编号0x010203,状态为当前故障)。 - 切换会话:发送
10 03,ECU返回50 03 00 32 01 F4(P2*=50ms,P2*_max=500ms)。 - 安全访问:发送
27 01,ECU返回种子67 01 00 11 22 33;计算密钥后发送27 02 44 55 66 77,ECU返回67 02。 - 清除DTC:发送
14 FF FF FF,ECU返回54。 - 验证:再次发送
19 02 09,ECU返回59 02 00(无DTC)。
结果与复盘:整个流程耗时约200ms(不含网络延迟)。关键风险点在于安全访问的密钥算法必须与ECU匹配,且延时锁定机制可能导致连续失败后无法立即重试。建议诊断仪在安全访问失败时记录失败次数,并提示用户等待延时结束。
UDS_ReadDTC()、UDS_ClearDTC()),内部处理会话切换、安全访问、超时重试等逻辑。这样上层应用无需关心协议细节,便于维护和扩展。