4、诊断协议基础:UDS协议概述、ISO 14229标准、诊断会话控制、DTC(诊断故障码)结构

各位好,欢迎来到第四讲。今天咱们聊聊诊断协议的基础。说实话,诊断这块内容,在HIL测试里是绕不开的硬骨头。你想想看,车上的ECU出了故障,总得有个标准化的方式去读取故障码、清除故障码、甚至做点在线编程吧?这就是UDS协议要干的事。

4.1 UDS协议概述

UDS,全称是Unified Diagnostic Services,统一诊断服务。说白了,它就是一套汽车电子系统里通用的“体检”和“治疗”语言。我最早接触UDS是在一个BMS项目中,当时被一堆0x10、0x19、0x14的十六进制数搞得头大。后来发现,其实它就像医院的挂号、问诊、开药流程,每个服务ID(SID)对应一个动作。

UDS的核心思想是“请求-响应”模式。诊断仪(Tester)发一个请求,ECU回一个响应。请求和响应都遵循固定的报文格式。我个人习惯把UDS报文拆成三部分看:

  • 服务ID(SID):告诉ECU你想干嘛。比如0x10是诊断会话控制,0x22是读取数据。
  • 子功能(Sub-function):进一步细化操作。比如0x10服务下,0x01是默认会话,0x02是编程会话。
  • 数据参数(Data):具体要读写的值或标识符。

举个例子,你想让ECU进入扩展诊断会话,发送的报文就是:02 10 03。其中02是报文长度,10是SID,03是子功能(扩展会话)。ECU如果支持,会回一个肯定响应:02 50 03。注意看,肯定响应的SID是请求SID+0x40,也就是0x10+0x40=0x50。

重要概念:UDS的响应分为肯定响应和否定响应。否定响应会带一个否定响应码(NRC),告诉你为什么请求被拒绝。比如0x12表示“子功能不支持”,0x22表示“条件不正确”。

4.2 ISO 14229标准

UDS的标准定义在ISO 14229里。这个标准定义了所有诊断服务的格式、时序、以及错误处理。嗯,这里要注意,ISO 14229只定义了应用层的内容,它不关心底层是CAN、LIN还是以太网。底层通信由ISO 15765(CAN上的诊断)或ISO 13400(以太网上的诊断)来管。

我记得有一次做HIL测试,发现ECU对某些诊断请求响应特别慢。查了半天,发现是底层CAN报文的分包策略没配好。ISO 14229里规定了单帧、多帧传输的规则,但具体怎么分包,得看底层协议。所以,做测试时一定要把应用层和传输层分开理解。

ISO 14229里定义的服务大概有20多个,常用的包括:

  • 0x10:诊断会话控制
  • 0x11:ECU复位
  • 0x14:清除诊断信息
  • 0x19:读取DTC信息
  • 0x22:读取数据标识符
  • 0x2E:写入数据标识符
  • 0x27:安全访问
  • 0x28:通信控制
  • 0x3E:Tester保持激活

你想想看,如果ECU不支持某个服务,你发过去它就会回一个否定响应,NRC通常是0x11(服务不支持)。所以,测试前最好先看看诊断规范,确认ECU支持哪些服务。

4.3 诊断会话控制

诊断会话控制(0x10服务)是UDS里最基础的服务之一。ECU上电后,默认处于默认会话(Default Session)。在这个会话里,很多诊断服务是被禁用的,比如编程、写入数据等。为什么?安全考虑。你总不希望随便一个诊断仪就能改写ECU的固件吧?

常见的会话类型有:

子功能 会话名称 说明
0x01 默认会话 上电后的初始状态,功能受限
0x02 编程会话 允许刷写固件,通常需要安全访问
0x03 扩展会话 允许读写数据、执行例程等
0x04 安全系统诊断会话 用于安全相关系统的诊断

我在项目中遇到过一个问题:ECU在扩展会话里待久了,会自动跳回默认会话。这是因为ECU有一个会话超时定时器(S3Server)。如果Tester长时间不发任何请求,ECU就会认为诊断会话结束了。所以,测试时记得定期发0x3E(Tester保持激活)请求,防止会话超时。

避坑指南:我曾经在测试中忘了发0x3E,结果ECU在编程中途跳回了默认会话,导致刷写失败。后来我养成了一个习惯:在测试脚本里加一个定时器,每2秒发一次0x3E,确保会话一直保持。

4.4 DTC(诊断故障码)结构

DTC,Diagnostic Trouble Code,诊断故障码。它是ECU用来报告故障的“暗号”。每个DTC对应一个特定的故障,比如“氧传感器信号异常”、“CAN总线通信丢失”等。

DTC的结构通常由三部分组成:

  • 故障码编号:一个4字节的十六进制数,比如P0100、U0100等。
  • 故障状态:一个字节,用位掩码表示故障的当前状态。比如bit0表示“测试失败”,bit1表示“当前故障”,bit2表示“历史故障”等。
  • 快照数据:故障发生时的环境数据,比如车速、发动机转速、冷却液温度等。用于故障复现和分析。

DTC的编号规则遵循ISO 15031-2标准,分为四个组:

首字符 系统类型 示例
P 动力系统 P0100(空气流量计故障)
C 底盘系统 C0035(左前轮速传感器故障)
B 车身系统 B1000(车身控制器内部故障)
U 网络通信 U0100(与ECM通信丢失)

在HIL测试中,我们经常需要模拟故障,然后读取DTC来验证ECU的诊断逻辑是否正确。比如,我模拟一个CAN总线断路,ECU应该报出U0100,并且故障状态位显示“当前故障”。如果ECU没报,或者报错了,那就是诊断逻辑有bug。

注意事项:DTC的清除不是随便清的。有些ECU要求必须先进入扩展会话,然后通过安全访问(0x27服务)解锁,才能执行清除DTC(0x14服务)。否则,ECU会返回否定响应。所以,测试脚本里一定要按正确的顺序来:先切会话,再安全访问,最后清除DTC。

好了,这一讲的内容就到这里。UDS协议是诊断测试的基石,理解它的报文结构、会话管理、以及DTC的编码规则,是做好HIL测试的前提。下一讲,我们会深入讨论如何用HIL系统模拟故障,并验证ECU的诊断响应。到时候见!