1. UDS诊断协议概述

大家好,我是你们这门课的老朋友。咱们今天开篇聊UDS,也就是统一诊断服务(Unified Diagnostic Services)。

说实话,我刚入行那会儿,对诊断协议也是一头雾水。那时候车上的ECU(电子控制单元)还没这么多,诊断也就是读读故障码。现在不一样了,一辆车几十上百个ECU,没有一套统一的诊断标准,维修站和产线根本没法干活。

UDS就是干这个的。它定义了一套标准化的“问话”和“回答”规则,让诊断工具(比如你手里的诊断仪)和车上的ECU能顺畅沟通。

1.1 UDS协议背景:为什么需要它?

在UDS出现之前,各家OEM(主机厂)都有自己的诊断协议。比如大众的KWP2000、福特的DCL,互不兼容。维修一个品牌的技师,换个品牌就得重新学一套指令。

这显然不是长久之计。国际标准化组织(ISO)出手了,在2006年发布了ISO 14229标准,也就是UDS。它统一了诊断服务的格式、流程和命名。

核心目标就三个:

  • 统一性:不管哪个品牌、哪个ECU,读故障码都用同一个服务ID(SID)。
  • 可扩展性:OEM可以在标准服务之外,自定义一些私有服务。
  • 安全性:不是谁都能随便改ECU数据,得有安全访问机制。
我个人的经验: 很多刚接触UDS的工程师,容易把UDS和OBD(车载诊断系统)搞混。OBD是法规强制要求的,主要管排放相关;UDS是整车厂自己定义的,覆盖全车所有ECU。说白了,OBD是“及格线”,UDS是“满分卷”。

1.2 OSI七层模型与UDS:它到底在哪一层?

你可能会问,UDS是软件还是协议?它工作在OSI模型的哪一层?

嗯,这个问题很关键。UDS本身是应用层(第7层)的协议。但它依赖下面的传输层和网络层来跑数据。

我画了一张图,帮你理清这个关系:

UDS在OSI模型中的位置 第7层:应用层 (UDS) 第6层:表示层 第5层:会话层 第4层:传输层 (DoIP/TCP) 第3层:网络层 (IP) 第2层:数据链路层 (CAN/以太网) 第1层:物理层 (CAN总线/以太网线) UDS服务 传输协议 总线硬件 UDS不关心底层是CAN还是以太网,它只定义“说什么”,不定义“怎么说”

你看,UDS在顶层,下面可以跑在CAN总线上(通过ISO 15765-2协议),也可以跑在以太网上(通过DoIP协议)。

常见的底层组合:

底层总线 传输协议 典型应用
CAN ISO 15765-2 (CAN TP) 传统动力域、车身域ECU
以太网 ISO 13400 (DoIP) ADAS、智能座舱、OTA升级
LIN ISO 17987 车窗、座椅等低速节点
避坑指南: 我曾经在一个项目里,把UDS报文长度算错了。CAN单帧最多传8字节,但UDS一个请求可能超过8字节,需要拆成多帧发送。如果你不熟悉CAN TP的分包机制,调试时会非常痛苦。后面我会专门讲这个。

1.3 UDS服务分类:到底有哪些“指令”?

UDS把诊断功能分成了几大类,每一类对应一个服务ID(SID)。SID是一个字节,范围是0x00到0x3E。

我按功能把它们分成了6组,你记一下:

  • 诊断管理类:0x10(诊断会话控制)、0x11(ECU复位)、0x3E(测试仪在线)
  • 数据读取类:0x22(按ID读数据)、0x23(按地址读内存)
  • 数据写入类:0x2E(按ID写数据)、0x3D(写内存)
  • 故障码类:0x14(读故障码信息)、0x19(读故障码数据)
  • 输入输出控制类:0x2F(控制输入输出)
  • 安全与上传下载类:0x27(安全访问)、0x34(请求下载)、0x36(传输数据)

你想想看,这些服务基本覆盖了ECU开发、测试、生产、售后全生命周期。比如产线上刷写软件,就用0x34/0x36/0x37这套流程。

核心要点: 每个服务都有固定的请求格式和响应格式。请求里包含SID和子功能(Sub-function),响应里包含SID+0x40(表示成功)或否定响应码(NRC)。

1.4 诊断会话与安全访问:ECU的“门禁系统”

ECU不是谁都能随便访问的。它有不同的“会话模式”,就像办公楼的门禁卡,不同卡能去的楼层不一样。

标准定义的三种会话:

会话名称 SID+子功能 用途
默认会话 (Default Session) 0x10 0x01 上电后的初始状态,只能读故障码和基本信息
编程会话 (Programming Session) 0x10 0x02 刷写软件、升级固件
扩展会话 (Extended Session) 0x10 0x03 标定、调试、读写参数

默认会话就像大厅,谁都能进。但你要进“编程室”或“标定室”,就得先切换会话,有时候还得通过安全访问验证。

安全访问(0x27服务)是ECU的一道锁。流程是这样的:

  1. 诊断仪发送0x27 0x01(请求种子)
  2. ECU返回一个随机种子(比如4字节数据)
  3. 诊断仪用特定算法计算密钥,发送0x27 0x02(发送密钥)
  4. ECU验证密钥,如果正确,解锁成功

说白了,这就是一个“挑战-应答”机制。种子是ECU出的题,密钥是诊断仪给的答案。

我建议: 开发阶段,很多工程师为了省事,把安全访问算法设成固定值或者直接跳过。千万别这么干!量产车如果被恶意刷写,后果很严重。安全访问算法一定要用非对称加密或者至少是复杂的多项式运算。

嗯,会话和安全访问是UDS里最容易出bug的地方之一。我记得有一次,一个同事在切换会话后忘了发0x3E(测试仪在线)保活报文,ECU自动跳回了默认会话,导致后续所有诊断请求都被拒绝。排查了半天才发现是会话超时了。

好了,这一章的内容就是这些。UDS的背景、OSI分层、服务分类、会话和安全访问,都是后面所有章节的基础。你把这些概念吃透了,后面学具体服务实现就会轻松很多。