UDS协议基础:服务分类与核心诊断服务
UDS(统一诊断服务)是汽车电子诊断的通用语言。说白了,它就是ECU和诊断仪之间约定好的一套“对话规则”。你发一个请求,ECU回一个响应,就这么简单。但背后的设计,其实挺讲究的。
我个人习惯把UDS服务分成三类:诊断管理类、数据类和通信类。今天咱们重点聊四个最基础的服务:会话控制(0x10)、安全访问(0x27)和通信控制(0x28)。这几个服务,几乎每个诊断栈都会用到。
UDS服务分类概览
UDS的服务标识符(SID)从0x00到0x3E,但常用的也就十几个。我按功能分了个类,你看这张表就明白了:
| 类别 | SID范围 | 典型服务 | 用途 |
|---|---|---|---|
| 诊断管理类 | 0x10 - 0x3E | 0x10(会话控制)、0x11(ECU复位)、0x27(安全访问) | 控制诊断会话、安全认证、ECU复位等管理操作 |
| 数据类 | 0x22 - 0x2E | 0x22(读取DID)、0x2E(写入DID)、0x23(读取内存) | 读写ECU内部数据、参数、标定值 |
| 通信类 | 0x28 - 0x29 | 0x28(通信控制)、0x29(诊断故障码控制) | 控制网络通信、DTC存储行为 |
你想想看,这三个类别其实对应了诊断的三个阶段:先建立会话(管理类),再验证身份(安全访问),最后读写数据或控制通信。顺序不能乱。
诊断会话控制(0x10)
0x10服务是诊断的“入口”。ECU上电后默认处于某个会话状态,诊断仪必须先发0x10请求,才能切换到目标会话。
会话类型主要有三种:
- 默认会话(0x01):ECU上电后的初始状态。功能受限,只能做基本诊断。
- 编程会话(0x02):用于刷写软件。我记得有一次项目,ECU在编程会话下才能解锁Flash写入权限。
- 扩展诊断会话(0x03):用于高级诊断功能,比如读写标定数据、执行例程。我建议你在开发阶段多用这个会话,功能最全。
请求格式很简单:
请求:0x10 + 会话类型(1字节)
响应:0x50 + 会话类型 + P2_Server_max(2字节)+ P2*_Server_max(2字节)
嗯,这里要注意:响应里的P2_Server_max和P2*_Server_max,分别表示ECU处理请求的最大时间和扩展时间。如果超时了,诊断仪得重发请求。我在项目中遇到过,有些ECU的P2时间设得很短,导致诊断仪频繁超时。后来我们统一把P2_Server_max设为50ms,才稳定下来。
安全访问(0x27)
0x27服务是用来“解锁”ECU的。为什么需要解锁?因为很多关键操作(比如刷写、标定)不能随便让任何人做。ECU会通过种子和密钥的校验,确认诊断仪是否合法。
流程分两步:
- 请求种子(0x27 + 子功能):诊断仪发请求,ECU返回一个随机种子(通常4字节)。
- 发送密钥(0x27 + 子功能+1):诊断仪用算法计算密钥,发给ECU。ECU比对后,返回成功或失败。
我曾经踩过一个坑:种子和密钥的算法,不同ECU可能不一样。有的用AES,有的用自定义异或。如果你在集成时发现安全访问总是失败,先检查算法是否匹配。
// 伪代码示例:安全访问流程
// 步骤1:请求种子
Request: 0x27 0x01
Response: 0x67 0x01 0x12 0x34 0x56 0x78 // 种子为0x12345678
// 步骤2:发送密钥(假设算法为种子+0x01020304)
Key = 0x12345678 + 0x01020304 = 0x1336597C
Request: 0x27 0x02 0x13 0x36 0x59 0x7C
Response: 0x67 0x02 // 成功
通信控制(0x28)
0x28服务用来控制ECU的网络通信行为。说白了,就是让ECU“闭嘴”或者“说话”。这在刷写时特别有用——你不想ECU在刷写过程中还忙着发CAN报文吧?
子功能主要有:
- 0x00:启用Rx和Tx——恢复正常通信。
- 0x01:禁用Rx和Tx——完全静默。
- 0x02:禁用Tx——只收不发。
- 0x03:禁用Rx——只发不收。
我记得有一次,客户反馈刷写时总线负载过高。后来发现是ECU在编程会话下还在发送周期报文。我们用0x28服务把Tx禁掉,问题就解决了。
请求格式:
请求:0x28 + 子功能(1字节)+ 通信类型(1字节)
响应:0x68 + 子功能
通信类型通常用0x01表示“所有网络”,但也可以指定特定网络(比如CAN、LIN)。
知识结构图
下面这张图,把今天讲的四个服务的关系画出来了。你可以看到,会话控制是入口,安全访问是门槛,通信控制是工具。三者配合,才能完成完整的诊断流程。
避坑指南
最后,分享几个我实际项目中遇到的坑:
- 会话超时:ECU在非默认会话下,如果一段时间没收到诊断请求,会自动切回默认会话。我建议你把超时时间设得长一点(比如5秒),避免调试时频繁断连。
- 安全访问锁死:有些ECU在安全访问失败5次后,会锁定30分钟。我曾经在测试时忘了重置计数器,结果等了大半个小时。嗯,后来我们加了个自动重置逻辑。
- 通信控制影响其他节点:禁用Rx/Tx时,要确认不会影响其他ECU的通信。比如,你禁掉了网关的Tx,可能导致整个网络瘫痪。