1、诊断基础入门:UDS协议概述、ISO 14229标准解读、诊断会话控制(0x10服务)详解

各位同学,咱们开始第一讲。

做汽车电子,诊断是绕不开的坎。不管你是做ECU开发、测试,还是做售后刷写,天天都得跟诊断打交道。我个人习惯把诊断比作「医生看病」——ECU就是病人,诊断仪就是听诊器,而UDS协议就是那套通用的医学术语。

1.1 UDS协议到底是什么?

UDS,全称Unified Diagnostic Services,统一诊断服务。说白了,它就是一套标准化的「问诊流程」。不管你是博世的ECU,还是大陆的ECU,只要它支持UDS,诊断仪就能用同样的方式跟它对话。

我刚开始接触诊断时,总觉得协议栈很神秘。后来发现,其实就是一问一答。诊断仪发一个请求,ECU回一个响应。就这么简单。

举个例子:

诊断仪请求:02 10 01
ECU响应:    06 50 01 00 32 01 F4

你看,这就是一次完整的诊断会话。02表示数据长度,10是服务ID,01是子功能。ECU回50表示成功,后面跟着一堆参数。

核心要点:UDS是应用层协议,它不关心底层是CAN还是LIN。你只要把诊断报文封装好,发出去就行。底层传输的事,交给CAN控制器去处理。

1.2 ISO 14229标准解读

ISO 14229就是UDS的官方标准文档。说实话,这玩意儿有几百页,没人会从头读到尾。但有几个关键点,你必须知道。

标准定义了三大类服务:

  • 诊断管理类:会话控制、安全访问、ECU复位等
  • 数据类:读取DID、写入DID、读取故障码等
  • 通信类:通信控制、链路保持等

我记得第一次看标准时,被那些服务ID搞得头晕。0x10、0x27、0x2E...后来我总结了一个规律:

服务ID 名称 我的记忆法
0x10 诊断会话控制 「10」= 开始会话
0x27 安全访问 「27」= 要钥匙(2把钥匙?)
0x2E 写入数据 「2E」= 2个E,写入要小心
0x22 读取数据 「22」= 2个2,读数据很简单

当然,这只是我个人的记忆法,你们可以有自己的方式。但记住,0x10是第一个要学的服务,因为所有诊断操作都得先建立会话。

小技巧:ISO 14229-1是核心标准,14229-2是会话层,14229-3是应用层。初学者先看14229-1就够了。别贪多,嚼不烂。

1.3 诊断会话控制(0x10服务)详解

好,重点来了。0x10服务,诊断会话控制。这是所有诊断操作的「敲门砖」。

为什么要有会话控制?

你想想看,ECU平时在车上跑,得保证安全。如果随便一个诊断仪都能改数据,那还得了?所以ECU设计了不同的会话模式,每种模式开放不同的权限。

三种标准会话模式:

  • 默认会话(0x01):上电后的初始状态,只能读一些基本信息。说白了就是「看看而已」。
  • 编程会话(0x02):用于刷写软件。权限最高,但风险也最大。
  • 扩展会话(0x03):用于读写数据、执行例程。日常诊断最常用的模式。

我在项目中遇到过一件事:有个同事刷写ECU时,直接发了编程会话请求,结果ECU没响应。查了半天,发现是ECU要求必须先进入扩展会话,才能切到编程会话。嗯,这就是协议栈的「安全锁」。

避坑指南:我曾经在测试时,连续发了10次会话切换请求,结果ECU直接锁死了。后来才知道,很多ECU有「防刷写保护」,短时间内频繁切换会话会被视为攻击。所以,每次切换会话后,至少等100ms再发下一条。

0x10服务的报文格式:

请求:02 10 01
  - 02:数据长度(2字节)
  - 10:服务ID(会话控制)
  - 01:子功能(默认会话)

响应:06 50 01 00 32 01 F4
  - 06:数据长度(6字节)
  - 50:响应服务ID(0x10 + 0x40)
  - 01:子功能(默认会话)
  - 00 32:P2时间(50ms)
  - 01 F4:P2*时间(500ms)

这里有个关键点:P2时间和P2*时间。P2是ECU处理请求的最大时间,超过这个时间没响应,诊断仪就得重发。P2*是扩展时间,用于处理耗时较长的操作。

我建议你们在CANalyzer里这样配置:

// 发送0x10请求
diagRequest ECU_Diag.SessionControl(Default);

// 等待响应
diagWaitResponse(ECU_Diag, 1000); // 超时1秒

// 检查响应
if (diagGetLastResponseCode() == 0x50) {
    write("会话切换成功");
} else {
    write("会话切换失败,错误码:" + hex(diagGetLastResponseCode()));
}

这段代码很简单,但很实用。我每次做诊断测试,都会先跑一遍这个流程,确认ECU能正常响应。

重要提醒:0x10服务不支持「否定响应抑制」位。也就是说,不管ECU同不同意切换,它都会给你一个响应。如果ECU返回0x7F(否定响应),后面会跟一个错误码。常见的错误码有:

  • 0x12:子功能不支持
  • 0x22:条件不满足(比如没上电)
  • 0x78:请求正确,但正在处理中

最后说一句,诊断会话控制看似简单,但它是所有诊断操作的基础。你想想看,如果连会话都建立不了,后面的安全访问、数据读写、刷写程序,全都白搭。所以,第一节课的内容,一定要吃透。

下一节,咱们讲安全访问(0x27服务),那个更有意思。到时候我会分享一个我踩过的坑——关于种子和密钥的算法问题。嗯,先卖个关子。