第3章:UDS协议概述
好,咱们进入正题。UDS协议,全称是Unified Diagnostic Services,统一诊断服务。说白了,它就是汽车电子世界里的一套“通用语言”。
我刚开始接触UDS时,觉得这东西挺玄乎。后来做项目多了才发现,它其实就是一套标准化的“问诊流程”。你想想看,医生看病有标准流程,汽车出故障了,也得有标准流程去查。UDS就是干这个的。
3.1 UDS协议栈长什么样?
UDS协议栈,不是真的“栈”,而是一个分层结构。我习惯把它想象成“七层汉堡”。
从下往上,大致是这么几层:
- 物理层:最底层,负责比特流的传输。CAN总线、以太网都行。
- 数据链路层:负责把数据打包成帧。CAN报文就是这一层干的。
- 网络层:ISO 15765-2(CAN TP)就在这层。它负责把长数据拆成小包,再拼回去。
- 传输层:嗯,有些资料把网络层和传输层合并了,咱们不纠结这个。
- 会话层:管理诊断会话。比如默认会话、扩展会话、编程会话。
- 表示层:数据格式转换。UDS的请求和响应格式就在这层定义。
- 应用层:最顶层,就是我们常说的UDS服务。比如读取故障码、写入数据。
我在项目中遇到过一个问题:明明发送了诊断请求,ECU就是不响应。查了半天,发现是网络层配置错了,CAN TP的发送间隔设得太短。嗯,这种坑踩过一次就记住了。
3.2 ISO 14229标准到底说了啥?
ISO 14229,就是UDS的“圣经”。它定义了所有诊断服务的格式、行为、时序。
这个标准分了好几个部分:
- ISO 14229-1:应用层规范。核心内容,定义了26个服务。
- ISO 14229-2:会话层规范。定义了诊断会话的切换规则。
- ISO 14229-3:UDSonCAN。专门针对CAN总线的实现。
- ISO 14229-4:UDSonFlexRay。针对FlexRay总线。
- ISO 14229-5:UDSonLIN。针对LIN总线。
- ISO 14229-6:UDSonEthernet。针对以太网。
你可能会问:“这么多部分,我该看哪个?”
我个人建议,先啃14229-1。把26个服务搞明白,其他部分都是“换汤不换药”。不同的总线,只是传输方式不同,服务本身是一样的。
3.3 服务分类:六大类,一个都不能少
UDS的26个服务,被分成了6大类。我按自己的理解,给你捋一捋。
| 分类 | 服务ID范围 | 典型服务 | 一句话说明 |
|---|---|---|---|
| 诊断与通信管理 | 0x10 - 0x3E | 0x10(诊断会话控制)、0x11(ECU复位)、0x3E(测试器存在) | 管理诊断会话和通信 |
| 数据传输 | 0x22 - 0x2E | 0x22(读取数据)、0x2E(写入数据) | 读写ECU内部数据 |
| 存储数据传输 | 0x14 - 0x19 | 0x14(清除诊断信息)、0x19(读取故障码) | 处理故障码和事件存储 |
| 输入输出控制 | 0x2F | 0x2F(输入输出控制) | 强制控制ECU的输入输出 |
| 远程激活 | 0x31 | 0x31(例程控制) | 启动ECU内部的特定程序 |
| 上传下载 | 0x34 - 0x37 | 0x34(请求下载)、0x36(传输数据)、0x37(请求退出传输) | 刷写ECU固件或数据 |
这六大类,我一个个说。
3.3.1 诊断与通信管理
这是UDS的“门卫”。你想跟ECU说话,得先通过它。
0x10 诊断会话控制:切换会话模式。默认会话(0x01)、扩展会话(0x02)、编程会话(0x03)。
我记得有一次,客户说ECU刷写失败。我一看日志,发现刷写前没切换到编程会话。ECU还在默认会话里,根本不接受刷写请求。这种低级错误,犯过一次就再也不会忘了。
0x11 ECU复位:让ECU重启。有硬复位、软复位、快速复位等类型。
0x3E 测试器存在:告诉ECU“我还活着”。如果ECU长时间收不到这个服务,会自动退出诊断会话。
3.3.2 数据传输
这是最常用的服务。说白了,就是读写ECU里的数据。
0x22 读取数据:按DID(数据标识符)读取数据。比如读VIN码、读软件版本、读传感器值。
0x2E 写入数据:按DID写入数据。比如写VIN码、写配置参数。
我习惯把DID想象成“抽屉的编号”。0x22就是打开抽屉看里面有什么,0x2E就是往抽屉里放东西。
3.3.3 存储数据传输
这一组专门处理故障码(DTC)。
0x14 清除诊断信息:清除故障码和冻结帧。
0x19 读取故障码:按各种条件读取DTC。可以读所有DTC、读当前激活的DTC、读历史DTC等。
0x19服务有好多子功能,我刚开始学的时候觉得头大。后来发现,记住最常用的几个就行:0x01(读取DTC数量)、0x02(读取DTC列表)、0x04(读取快照数据)。
3.3.4 输入输出控制
这个服务很“暴力”。它可以直接控制ECU的输入输出。
0x2F 输入输出控制:强制某个引脚输出高电平、低电平、或者PWM波。
我在项目中用过这个服务来测试执行器。比如强制打开风扇、强制关闭大灯。调试硬件时特别好用。
3.3.5 远程激活
这个服务用来启动ECU内部的“小程序”。
0x31 例程控制:启动、停止、查询某个例程。比如启动自检例程、启动校准例程。
例程有点像手机上的“快捷指令”。你告诉ECU“执行这个程序”,ECU就跑一遍,然后告诉你结果。
3.3.6 上传下载
这一组是刷写固件的核心。
0x34 请求下载:告诉ECU“我要发数据了”。ECU会告诉你“准备好了,发吧”。
0x36 传输数据:把数据一块一块地发给ECU。每块最大4095字节。
0x37 请求退出传输:告诉ECU“数据发完了”。ECU会检查完整性,然后退出传输模式。
刷写固件时,这三个服务要配合使用。我见过有人把0x34和0x36的顺序搞反了,结果ECU直接拒绝通信。嗯,顺序很重要。
3.4 我的学习建议
学UDS,别想着一天吃成胖子。我建议你:
- 先记住六大类的名字:诊断与通信管理、数据传输、存储数据传输、输入输出控制、远程激活、上传下载。
- 再记住每个大类里的核心服务:比如0x10、0x22、0x19、0x2F、0x31、0x34。
- 最后去啃ISO 14229-1:把每个服务的请求和响应格式看一遍。
我曾经带过一个新人,他花了一周时间把26个服务的ID背得滚瓜烂熟。结果一上项目,连0x22和0x2E都分不清。为什么?因为他只背了ID,没理解服务是干什么的。
所以,理解比记忆更重要。你想想看,你不需要记住每个服务的ID,但你需要知道“我想读数据,该用哪个服务”。
好了,这一章就到这里。下一章,咱们聊聊UDS的报文格式和时序。这东西搞明白了,你就能看懂诊断日志了。