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的诊断响应。到时候见!