4、UDS应用层核心服务:诊断会话控制服务、ECU复位服务、安全访问服务、通信控制服务

UDS协议的应用层,说白了就是一堆定义好的“服务”。每个服务都有一个唯一的SID(服务标识符)。你发一个请求,ECU回一个响应,就这么简单。

但简单归简单,这4个服务是诊断的基石。我做了这么多年,几乎每个项目都会跟它们打交道。今天咱们就把它们彻底讲透。

核心要点: 这4个服务分别控制ECU的“工作模式”、“重启行为”、“安全锁”和“通信开关”。它们是所有上层诊断功能的基础。
UDS 四大核心服务关系图 UDS 诊断应用层 诊断会话控制 (0x10) ECU复位 (0x11) 安全访问 (0x27) 通信控制 (0x28) 应用场景说明 • 诊断会话控制:切换ECU的工作模式(默认/编程/扩展) • ECU复位:强制ECU重启,常用于刷写后激活新软件 • 安全访问:解锁ECU的“安全锁”,才能进行敏感操作

4.1 诊断会话控制服务 (0x10)

这个服务,我习惯叫它“换挡”。ECU上电后默认在默认会话(Default Session)里。你想干点“高级”的事,比如刷写软件、读一些敏感数据,就得先切换到对应的会话。

会话类型 SID + Sub 典型用途
默认会话 0x10 0x01 上电后的基础状态,只支持基本诊断服务
编程会话 0x10 0x02 刷写软件、配置参数
扩展会话 0x10 0x03 高级标定、特殊功能测试
我的经验: 切换会话时,ECU可能会退出之前的会话。比如你在扩展会话里做标定,一切换到编程会话,标定数据可能就丢了。所以,切换前一定要确认当前工作状态。

请求格式很简单:0x10 + sub-function。比如切换到编程会话,就发 02 10 02(假设CAN ID是0x7DF)。

// 请求示例:切换到编程会话
// CAN ID: 0x7DF
// 数据: 02 10 02
// 解释: 02表示后面有2个字节,10是SID,02是编程会话子功能

// 肯定响应示例
// CAN ID: 0x7E8
// 数据: 02 50 02
// 解释: 50 = 10 + 0x40,表示肯定响应,02表示当前在编程会话
注意: 如果ECU不支持你请求的会话,会返回否定响应码 0x12(子功能不支持)或 0x22(条件不满足)。我曾经遇到过,ECU必须在特定条件下才能进入编程会话,比如车速为0、点火开关打开等。

4.2 ECU复位服务 (0x11)

这个服务,说白了就是让ECU“重启”。你想想看,刷完软件后,总得让ECU重新跑一遍新代码吧?

复位类型 子功能 行为
硬复位 0x01 模拟断电再上电,ECU完全重启
钥匙通断复位 0x02 模拟点火开关OFF再ON,部分ECU会保持一些RAM数据
软复位 0x03 仅复位软件,不涉及硬件电源
使能快速路由 0x04 用于网关快速转发诊断请求,不常用

请求格式:0x11 + sub-function。比如硬复位,就发 02 11 01。

// 请求示例:硬复位
// CAN ID: 0x7DF
// 数据: 02 11 01

// 肯定响应示例
// CAN ID: 0x7E8
// 数据: 02 51 01
// 解释: 51 = 11 + 0x40,表示肯定响应
关键点: ECU收到复位请求后,会先发肯定响应,然后才执行复位。但复位后,ECU会回到默认会话。所以,如果你在编程会话里复位,复位后需要重新切换会话。
避坑指南: 我曾经在项目中遇到一个问题:ECU复位后,CAN控制器初始化需要时间。如果诊断仪在复位后立即发送请求,ECU可能还没准备好,导致通信失败。所以,复位后建议等待至少100ms再发下一个请求。

4.3 安全访问服务 (0x27)

这个服务,我习惯叫它“开锁”。ECU里有些敏感数据,比如刷写密钥、标定参数,不能随便让人读或写。你得先通过“安全访问”验证身份。

流程是这样的:

  1. 请求种子: 诊断仪发 0x27 0x01(请求种子),ECU返回一个随机数(种子)。
  2. 发送密钥: 诊断仪用种子和算法计算出一个密钥,发 0x27 0x02 + 密钥。
  3. 验证: ECU用同样的算法计算,如果密钥匹配,就解锁成功。
步骤 方向 数据示例 说明
1. 请求种子 诊断仪 → ECU 02 27 01 请求种子(level 1)
2. 发送种子 ECU → 诊断仪 04 67 01 AA BB CC DD 种子是 0xAABBCCDD
3. 发送密钥 诊断仪 → ECU 06 27 02 11 22 33 44 密钥是 0x11223344
4. 验证结果 ECU → 诊断仪 02 67 02 肯定响应,解锁成功
我的经验: 安全访问算法通常是保密的,由OEM定义。我见过用简单的异或,也见过用AES加密的。但不管算法多复杂,流程都一样。另外,解锁后通常有超时机制,比如5秒内没操作,ECU会自动上锁。
注意: 如果密钥错误,ECU会返回否定响应码 0x35(无效密钥)。连续错误次数过多,ECU可能会锁定安全访问功能一段时间(比如30秒)。这是为了防止暴力破解。

4.4 通信控制服务 (0x28)

这个服务,说白了就是“开关”。你可以控制ECU的某些通信通道,比如关闭应用报文、只保留诊断报文。这在刷写时特别有用——你不想让ECU在刷写过程中还忙着发CAN报文吧?

控制类型 子功能 效果
启用Rx和Tx 0x00 恢复正常通信
禁用Rx和Tx 0x01 完全静默,只响应诊断请求
禁用Tx 0x02 ECU不发任何报文,但能收
禁用Rx 0x03 ECU不收任何报文,但能发
禁用特定网络Tx 0x04 只禁用某个CAN网络的发送

请求格式:0x28 + sub-function + [通信类型]。比如禁用所有应用报文,只保留诊断报文,就发 03 28 01 03(03表示后面有3个字节,28是SID,01是禁用Rx和Tx,03是应用报文)。

// 请求示例:禁用应用报文(Rx和Tx)
// CAN ID: 0x7DF
// 数据: 03 28 01 03
// 解释: 01 = 禁用Rx和Tx,03 = 应用报文

// 肯定响应示例
// CAN ID: 0x7E8
// 数据: 02 68 01
// 解释: 68 = 28 + 0x40,表示肯定响应
关键点: 通信控制服务通常配合编程会话使用。刷写前,先切换到编程会话,然后禁用应用报文,这样刷写过程中就不会被其他报文干扰。刷写完成后,再启用通信,恢复ECU的正常工作。
我的经验: 有些ECU在禁用通信后,会进入一种“半休眠”状态。如果你在禁用通信后发送诊断请求,ECU可能响应很慢。所以,我建议在禁用通信后,先发一个“Tester Present”请求,确认ECU还活着。