汽车诊断基础:UDS协议概述、诊断会话控制、安全访问、故障码读取与清除等核心服务

UDS(Unified Diagnostic Services,统一诊断服务)是ISO 14229标准定义的一套应用层诊断协议,它规范了诊断仪(Tester)与ECU(电子控制单元)之间的通信规则。在DoIP(Diagnostic over Internet Protocol,基于以太网的诊断)体系中,UDS作为应用层协议承载于TCP/UDP之上,是诊断仪开发工程师必须掌握的核心知识。本章将围绕UDS协议的核心服务展开,重点讲解诊断会话控制(0x10)、安全访问(0x27)、故障码读取(0x19)与清除(0x14)等关键服务的实现原理、报文格式、时序要求及工程实践中的常见问题。

UDS核心服务关系与诊断流程 诊断仪 (Tester) DoIP客户端 ECU (Server) DoIP服务端 DoIP (TCP/UDP) 0x10 会话控制 默认/编程/扩展 0x27 安全访问 种子与密钥 0x19 读取DTC 按状态/掩码 0x14 清除DTC 清除故障码 典型诊断时序 ① 建立连接 (DoIP) ② 0x10 进入扩展会话 ③ 0x27 安全解锁 ④ 0x19 读取DTC 关键要点: • 0x10 用于切换诊断会话,不同会话下可用的服务集合不同 • 0x27 需要先请求种子(seed),再发送密钥(key),防止未授权访问 • 0x19 支持多种子功能,如按DTC状态掩码读取、按DTC编号读取等 • 0x14 清除DTC前通常需要安全解锁,且清除后需重新读取确认

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下载相关服务。

工程提示:在DoIP开发中,UDS报文的最大长度受限于DoIP的Payload Type和TCP分段机制。对于超过底层MTU(最大传输单元)的UDS报文,需要依赖TCP的流控机制保证完整接收。建议在诊断仪设计中预留至少4KB的接收缓冲区,以应对多帧响应(如0x19读取大量DTC信息时)。

诊断会话控制(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
风险提示:在编程会话下,ECU可能关闭部分通信报文(如CAN上的应用报文),仅保留诊断通信。若诊断仪在编程会话中异常掉线,ECU可能因看门狗超时而复位。因此,诊断仪必须实现会话保持机制(周期性发送0x3E服务)或快速完成编程操作。

安全访问(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(延时未到)。

安全访问的工程实现要点:

  1. 种子长度:通常为4字节或8字节,具体长度由ECU厂商定义。
  2. 密钥算法:常见算法包括CRC16、AES-128、自定义查表法。算法必须与ECU端完全一致。
  3. 延时机制:ECU在连续失败后(通常3次)会进入延时锁定状态(如10秒内禁止再次尝试)。诊断仪应实现失败计数和延时等待逻辑。
  4. 会话关联:安全解锁状态通常与会话绑定,切换会话后需重新解锁。
实战场景:某ECU在扩展会话下需要安全访问Level 1才能执行0x2E写入VIN码。诊断仪发送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信息0x190x01(按编号)、0x02(按状态)、0x04(快照)0x31(请求超出范围)、0x22(条件不满足)注意DTC编号格式(3字节),状态掩码位定义
清除DTC0x14无(固定参数0xFFFFFF)0x72(一般编程失败)、0x33(安全访问被拒绝)清除前需安全解锁,清除后需重新读取确认
常见误区:很多初学者认为清除DTC后故障灯会立即熄灭。实际上,DTC清除只是删除了ECU内存中的故障记录,故障灯状态由ECU的故障管理策略决定。如果故障仍然存在,ECU会在下一次检测周期重新报出DTC。因此,诊断仪在清除DTC后应提示用户进行路试或功能验证,而不是直接判定故障已修复。

案例拆解:DoIP诊断仪读取并清除DTC的完整流程

以下是一个典型的DoIP诊断仪操作案例,展示从建立连接到清除DTC的完整流程。

背景与约束:某OEM的ECU支持DoIP诊断,诊断仪需通过以太网连接车辆网关,网关再路由到目标ECU。ECU在默认会话下允许读取DTC,但清除DTC需要切换到扩展会话并完成安全访问Level 1。

操作步骤:

  1. 建立DoIP连接:诊断仪发送DoIP车辆识别请求(VIN),网关返回车辆信息,诊断仪建立TCP连接。
  2. 读取DTC:发送19 02 09,ECU返回59 02 01 01 02 03 09(表示1个DTC,编号0x010203,状态为当前故障)。
  3. 切换会话:发送10 03,ECU返回50 03 00 32 01 F4(P2*=50ms,P2*_max=500ms)。
  4. 安全访问:发送27 01,ECU返回种子67 01 00 11 22 33;计算密钥后发送27 02 44 55 66 77,ECU返回67 02。
  5. 清除DTC:发送14 FF FF FF,ECU返回54。
  6. 验证:再次发送19 02 09,ECU返回59 02 00(无DTC)。

结果与复盘:整个流程耗时约200ms(不含网络延迟)。关键风险点在于安全访问的密钥算法必须与ECU匹配,且延时锁定机制可能导致连续失败后无法立即重试。建议诊断仪在安全访问失败时记录失败次数,并提示用户等待延时结束。

经验总结:在DoIP诊断开发中,建议将UDS服务封装为独立的模块,提供统一的API接口(如UDS_ReadDTC()、UDS_ClearDTC()),内部处理会话切换、安全访问、超时重试等逻辑。这样上层应用无需关心协议细节,便于维护和扩展。