第1章:UDS服务分类与寻址机制
大家好,我是老张。做汽车嵌入式这行十几年了,UDS诊断协议几乎天天打交道。今天咱们聊聊UDS服务的基础框架——服务分类、寻址方式,还有SID和RSID的结构。
说实话,刚入行那会儿,我也被这些概念搞得晕头转向。后来踩过几次坑,才真正理解这些设计背后的逻辑。嗯,咱们一步步来。
1.1 强制服务与可选服务
UDS协议里,服务不是你想用哪个就用哪个。它分两类:强制服务和可选服务。
强制服务,说白了就是ECU必须支持的。你想想看,如果连最基本的诊断会话控制都不支持,那这ECU压根没法做诊断。ISO 14229里明确规定了哪些是强制服务。
我列个表,大家看得更清楚:
| 服务类别 | 服务ID (SID) | 服务名称 | 强制/可选 |
|---|---|---|---|
| 诊断和通信管理 | 0x10 | 诊断会话控制 | 强制 |
| 诊断和通信管理 | 0x11 | ECU复位 | 强制 |
| 诊断和通信管理 | 0x27 | 安全访问 | 可选 |
| 数据传输 | 0x22 | 读取数据标识符 | 强制 |
| 数据传输 | 0x2E | 写入数据标识符 | 可选 |
| 存储数据传输 | 0x14 | 清除诊断信息 | 强制 |
| 存储数据传输 | 0x19 | 读取故障码信息 | 强制 |
我个人习惯,在项目初期就会把强制服务列表拉出来,挨个确认ECU是否支持。有一次项目赶进度,有个同事漏了0x11(ECU复位)的实现,结果在整车测试时死活过不了。嗯,这个坑我记忆犹新。
重要提醒:强制服务是UDS合规性的底线。如果你的ECU声称支持UDS,那强制服务一个都不能少。
可选服务呢?比如0x27安全访问、0x2E写入数据标识符。这些看具体需求。但要注意,如果你实现了可选服务,那它的行为必须完全符合协议规范,不能自己瞎改。
1.2 功能寻址与物理寻址
这是UDS里一个非常关键的概念。我刚开始做诊断时,就搞混过这两个寻址方式,结果把整个总线上的ECU都复位了...那场面,尴尬得很。
物理寻址:一对一的通信。一个诊断请求只发给一个特定的ECU。每个ECU有自己唯一的物理地址。
功能寻址:一对多的通信。一个诊断请求可以发给一组ECU,甚至所有ECU。功能地址是广播式的。
举个例子:
- 你想读取发动机ECU的故障码,用物理寻址,只发给发动机ECU。
- 你想让所有ECU都进入扩展诊断会话,用功能寻址,一条消息搞定所有。
为什么要有这两种方式?你想想看,在整车生产线上,需要同时给所有ECU刷写软件。如果用物理寻址,得一个一个来,效率太低。功能寻址一条广播就搞定了。
我的经验:功能寻址虽然方便,但风险也大。我曾经在调试时不小心用功能寻址发了ECU复位指令,结果整个台架上的ECU全复位了,日志全丢了。从那以后,我写测试脚本时,功能寻址的指令都会加个确认弹窗。
在CAN总线上,物理寻址和功能寻址是通过CAN ID来区分的。一般来说:
- 物理请求ID:0x7E0(诊断仪到ECU),0x7E8(ECU响应)
- 功能请求ID:0x7DF(诊断仪到所有ECU)
当然,具体ID分配要看整车厂的定义,但原理是一样的。
1.3 服务ID(SID)与响应ID(RSID)结构
每个UDS服务都有自己唯一的ID,叫SID(Service ID)。比如0x10是诊断会话控制,0x22是读取数据标识符。
那响应ID呢?RSID(Response Service ID) = SID + 0x40。这是协议规定的。
举个例子:
- 请求:0x22 0xF1 0x90(读取VIN码)
- 响应:0x62 0xF1 0x90 0x31 0x32 0x33...(0x62 = 0x22 + 0x40)
为什么这么设计?说白了,就是让接收方能一眼区分这是请求还是响应。你收到一个报文,看第一个字节:
- 如果小于0x40,那就是请求
- 如果大于等于0x40,那就是响应
这个设计很巧妙,对吧?
注意:响应还有两种:肯定响应和否定响应。肯定响应的RSID = SID + 0x40。否定响应的第一个字节是0x7F,后面跟着SID和错误码。这个后面章节会详细讲。
我给大家看个实际报文例子:
// 诊断请求:读取VIN码
发送:22 F1 90
// 肯定响应:VIN码为"LSVA12345..."
接收:62 F1 90 4C 53 56 41 31 32 33 34 35 2E 2E 2E
// 否定响应:不支持该服务
接收:7F 22 11 // 0x11 = 服务不支持
嗯,这里要注意,否定响应的结构是固定的:0x7F + SID + NRC(否定响应码)。这个NRC后面会专门讲,常见的比如0x11(服务不支持)、0x12(子功能不支持)、0x13(报文长度错误)等等。
1.4 小结
今天咱们聊了三个核心概念:
- 服务分类:强制服务必须实现,可选服务按需实现
- 寻址方式:物理寻址一对一,功能寻址一对多,各有各的用途
- SID/RSID结构:RSID = SID + 0x40,否定响应以0x7F开头
这些是UDS诊断的基础中的基础。我个人觉得,理解这些概念比背协议更重要。因为实际项目中,你遇到的不会是教科书式的完美场景,而是各种边界情况和异常处理。
下一章,咱们聊聊诊断会话管理,这可是UDS的入口。没有会话,啥服务都跑不起来。
课后思考:如果你设计一个诊断协议,你会怎么区分请求和响应?为什么UDS选择用SID+0x40的方式,而不是用单独的标志位?
公众号:蓝海资料掘金营,微信deep3321