在 ISO 14229 UDS 体系里,SID 0x22 也就是 ReadDataByIdentifier,是整车诊断里使用频率最高的基础服务,诊断客户端依靠 2 字节 DID(数据标识符)向 ECU 请求读取一条或者多条数据记录,没有子功能,全部靠 DID 来定义读取目标;它既能读取静态信息,比如 VIN、硬件版本、序列号,也能读取动态实时传感器数据,像转速、车速、电压,同时这套服务受诊断会话、安全访问、整车运行条件三重限制,部分加密 DID 需要先走 0x27 安全解锁才能读取,报文过长还会走 ISO‑TP 多帧分包,和配套写服务 SID 0x2E 成对使用,是标定、下线、售后、台架测试的核心入口。
服务基础定义
- 服务名称:ReadDataByIdentifier
- SID:0x22
- 肯定响应 SID:0x62(0x22 + 0x40)
- 否定响应格式:0x7F 22 + NRC
- 子功能:无,和 0x10、0x19 这类带子功能的服务区分开
- DID:固定 16 位,2 字节,分 ISO 标准预留段、厂商自定义段
- 底层传输:依托 CAN ISO‑TP(ISO 15765‑2),短报文单帧,长数据自动拆连续帧
- 配对服务:SID 0x2E WriteDataByIdentifier,用来写入对应 DID
请求、正响应报文格式
请求报文
| 字节 | 字段 | 说明 |
|---|---|---|
| 0 | SID | 固定 0x22 |
| 1~2 | DID1_H、DID1_L | 第一个待读取 DID |
| 3~4 | DID2_H、DID2_L | 可选,第二个 DID,支持一次请求多个 DID |
| 后续 | …… | 继续追加更多 DID |
示例(读取 VIN,DID 0xF190):22 F1 90
肯定响应报文
| 字节 | 字段 | 说明 |
|---|---|---|
| 0 | 正响应 SID | 固定 0x62 |
| 1~2 | DID_H、DID_L | 回显刚才请求的 DID,顺序和请求保持一致 |
| 3~N | dataRecord | 该 DID 对应的原始数据,长度、缩放、字节序由项目 DBC / 诊断规范定义 |
示例:62 F1 90 57 44 4B ...,后面跟着 17 字节 ASCII VIN 码
多 DID 读取规则:请求顺序是什么,返回就按同样顺序,每一组都是 DID + 对应数据;ECU 不会给不支持的 DID 填空占位,如果其中一部分 DID 不支持,只返回能读到的;全部 DID 都不支持才返回负响应 0x31。
高频标准 DID 清单
- 0xF190:VIN 车辆识别码,17 字节 ASCII
- 0xF187:备件号 / 零件号
- 0xF189:ECU 软件版本号
- 0xF18A:供应商 ID
- 0xF18B:ECU 制造日期
- 0xF18C:ECU 序列号
- 0x0101:车辆车速
- 0x0102:发动机转速
- 0x010A:油门开度
注意:0xF100~0xF1FF 属于 ISO 预留整车信息段;其余大量 DID 是主机厂自定义,必须查对应诊断规范,不能直接套用通用表。
常用负响应 NRC 对照表
| NRC | 名称 | 场景说明 |
|---|---|---|
| 0x13 | IncorrectMessageLengthOrInvalidFormat | 报文长度不对、格式非法 |
| 0x14 | ResponseTooLong | 多个 DID 一起读,响应总长度超出 ISO‑TP 缓冲区上限 |
| 0x22 | ConditionsNotCorrect | 整车条件不满足,比如引擎状态、挡位、车速限制不让读 |
| 0x31 | RequestOutOfRange | 请求的 DID 在当前会话不存在、未实现 |
| 0x33 | SecurityAccessDenied | 该 DID 有安全锁,没有完成 0x27 解锁 |
| 0x7F | ServiceNotSupportedInActiveSession | 当前诊断会话不开放该服务,比如默认会话禁止 |
完整通信流程
- 诊断仪(客户端)先确认当前诊断会话,部分 DID 要求先切扩展会话 0x10 0x03。
- 如果目标 DID 带有安全保护,先调用 SID 0x27 安全访问,拿到安全解锁。
- 组包发送 0x22 请求,里面带上一个或者连续多个 2 字节 DID。
- ECU 校验报文长度、会话权限、安全状态、整车工况。
- 校验全部通过,返回 0x62 正响应,回显 DID + 原始数据;数据过长由 ISO‑TP 自动拆分连续帧、流控重组。
- 校验失败,返回 0x7F 22 + NRC,诊断工具根据错误码定位问题。
- 读取完成之后,如果需要修改参数,再使用 SID 0x2E 写入对应 DID。
权限与工程限制
✅ 会话限制:部分 DID 在默认会话不让读,必须进入扩展会话;编程会话里开放的 DID 又是另一套。
✅ 安全锁:标定、下线配置、加密序列号类 DID,强制安全访问解锁,锁状态直接返回 0x33。
✅ 整车条件锁:比如行驶中禁止读取某些标定参数,熄火状态不能读取动态转速数据。
✅ 多 DID 上限:虽然标准允许一条请求带多个 DID,但 ECU 内部有缓冲区上限,一次性塞太多 DID 容易触发 0x14。
✅ 数据解析:原始 dataRecord 只是原始字节,转速、温度、电压都需要配套缩放公式、偏移量才能转换成工程值,不能直接拿来用。
开发、测试高频踩坑点
- 很多新人以为 DID 全局通用,直接拿别的项目的 DID 表,结果报 0x31;厂商自定义 DID 必须看项目诊断规范。
- 多 DID 请求时,只要有一个 DID 需要安全访问,整条请求都会被拒绝,建议分开请求。
- VIN、版本号这类长数据会触发多帧,如果工具没有正确开启 ISO‑TP,直接丢包、解析乱码。
- 拿到正响应只看 0x62,忽略回显的 DID,当顺序错乱、ECU 跳过不支持项的时候,数据和 DID 错位。
- 和 0x2E 配对调试,写入成功,但是读回来不一样,大多是字节序、缩放、存储端没对齐。
【常见问题】
问题 1:UDS SID 0x22 ReadDataByIdentifier,这个服务有没有子功能?
回答 1:UDS SID 0x22 ReadDataByIdentifier 没有子功能,读取目标完全由后面的 2 字节 DID 决定,和 0x10、0x19 这类带子功能的 UDS 服务不一样。
问题 2:UDS ReadDataByIdentifier(SID 0x22)正响应开头为什么是 0x62?
回答 2:UDS ReadDataByIdentifier(SID 0x22)的正响应规则是请求 SID 加上 0x40,也就是 0x22 + 0x40 = 0x62,后面紧跟着回显的 DID 和对应数据记录。
问题 3:发送 UDS SID 0x22 读取 DID,返回 NRC 0x33,代表什么?
回答 3:UDS SID 0x22 返回 NRC 0x33(SecurityAccessDenied),说明当前读取的 DID 带有安全访问保护,需要先执行 SID 0x27 安全解锁之后,才能调用 ReadDataByIdentifier 读取。
问题 4:UDS ReadDataByIdentifier(SID 0x22)能不能一次报文读取多个 DID?
回答 4:可以,UDS ReadDataByIdentifier(SID 0x22)支持单条请求报文携带多个 DID,ECU 会按请求顺序返回支持的 DID 及其数据;但受 ECU 缓冲区限制,数量过多会触发 0x14 响应过长报错。
【参考资料】
[2026-11-15](详解 UDS CAN 诊断:ReadDataByIdentifier Service (SID:0x22))电子工程专辑
[2026-11-14](详解 UDS CAN 诊断:ReadDataByIdentifier Service (SID:0x22))CSDN 博客
[2026-10-30](0x22 ReadDataByIdentifier — UDS DID Read)udssimulator.com
[2026-05-24](UDS-Diagnoseprotokoll ISO14229 Service 0x22)KFZ Dietrich
[2022-05-25](UDS 诊断之 22/2E 服务)腾讯云开发者社区
【免责声明】
本文整理自 ISO 14229‑1 标准文档、诊断开源文档、汽车工程媒体公开资料;UDS ReadDataByIdentifier(SID 0x22)的 DID 分配、缩放公式、会话权限、安全策略高度依赖主机厂项目规范;本文仅为协议原理科普,不替代整车诊断规范、DBC 文件、ECU 需求文档;整车刷写、诊断调试操作存在车辆风险,相关调试工作请在台架或者安全环境、由持证工程师完成。
