网易首页 > 网易号 > 正文 申请入驻

UDS 诊断服务之 0x22 – 通过标识符读取数据

0
分享至


1. 服务概述

在统一诊断服务(UDS,ISO 14229)中,0x22 – ReadDataByIdentifier是一个最常用的读取服务。它允许诊断工具(Tester)向电子控制单元(ECU)请求一个或几个特定标识符(DID,Data Identifier)对应的数据。这些数据可以是 ECU 的硬/软件版本、车辆识别码(VIN)、序列号、当前会话类型、标定参数,甚至是实时采集的里程、电压、车窗位置等动态信号。

主要特点:

  • 支持读取一个或多个 DID(最多由底层传输协议决定)。

  • DID 占 2 个字节(0x0000 – 0xFFFF),由 ECU 供应商定义。

  • 响应返回 DID 及其对应的原始字节数据。

2. 报文格式 2.1 请求报文

字节偏移

参数名

值(hex)

描述

0

Service ID

0x22

请求服务标识符

1

DID high byte

0xF1

DID 高字节

2

DID low byte

0x8C

DID 低字节

更多 DID(可选)

0xF1 0x90

连续提供多个 DID(2字节/个)

示例请求:22 F1 8C
含义:读取 DID = 0xF18C(ECU 序列号)。

2.2 肯定响应

字节偏移

参数名

值(hex)

描述

0

Response ID

0x62

肯定响应标识符(=0x22+0x40)

1

DID high byte

0xF1

原请求中的 DID 高字节

2

DID low byte

0x8C

原请求中的 DID 低字节

3..n

Data Record

12 34 56 78

该 DID 对应的数据(长度可变)

示例响应:62 F1 8C 12 34 56 78
含义:DID 0xF18C 的数据是 4 个字节0x12,0x34,0x56,0x78。

2.3 否定响应(NRC)

当请求不符合规范或 ECU 无法处理时,返回7F+ SID + NRC:

NRC 代码

含义

0x13

消息长度/格式错误

0x14

数据太长

0x22

条件不满足(如安全等级不足)

0x31

请求超出范围(DID 不支持)


3. 常用 DID 示例(非标准,厂家自定)

DID

描述

数据长度示例

数据内容示意

0xF18C

ECU 序列号

8 字节

"SN123456"

0xF190

VIN码

17 字节

"LFV3A23K9P3123456"

0xF186

当前会话

1 字节

0x01

(默认会话)

0xF187

软件版本

4 字节

0x01 0x02 0x03 0x00

0x1000

当前里程(km)

4 字节

0x00 0x00 0x12 0x34

(4660km)

0x1001

蓄电池电压(mV)

2 字节

0x0D 0x48

(3400mV)


注意:DID 及其含义完全由 ECU 供应商决定。ISO 14229 中仅保留 0x0000–0x00FF 为标准 DID(如 0xF190 常用作 VIN,但不是强制标准)。
4. C++ 代码实现举例

下面给出一个简化但完整的 C++ 示例,模拟 ECU 中的0x22 服务处理逻辑。
代码包含:

  • 一个 DID 数据表(std::map存储 DID 与其字节数据)

  • 解析请求、查找 DID、构造响应

  • 支持单个 DID 读取

  • 处理不支持 DID 的错误(返回 NRC 0x31)

4.1 环境说明
  • C++17 及以上(使用std::vector、std::map)

  • 假设底层 CAN/DoCAN 已剥离传输协议,仅处理应用层消息(完整 UDS 长度 ≤ 8 字节)

4.2 完整代码

#include  

#include
#include
#include
#include

// 模拟 ECU 内部的 DID 数据存储器
class DidStorage {
public:
DidStorage() {
// 初始化一些示例 DID 数据
// DID 0xF18C : ECU 序列号 (8字节)
store[0xF18C] = {0x53, 0x4E, 0x30, 0x30, 0x31, 0x32, 0x33, 0x34}; // "SN001234"
// DID 0xF190 : VIN码 (17字节)
store[0xF190] = {0x4C, 0x46, 0x56, 0x33, 0x41, 0x32, 0x33, 0x4B,
0x39, 0x50, 0x33, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36}; // "LFV3A23K9P3123456"
// DID 0xF186 : 当前会话 (1字节)
store[0xF186] = {0x01}; // 默认会话
// DID 0x1000 : 里程,单位 km (4字节,小端)
store[0x1000] = {0x34, 0x12, 0x00, 0x00}; // 0x1234 = 4660 km
}

// 根据 DID 获取数据,若不存在返回 nullptr
const std::vector* getData(uint16_t did) const {
auto it = store.find(did);
if (it != store.end()) {
return &(it->second);
}
return nullptr;
}

private:
std::map> store;
};

// 处理 0x22 服务请求
// 输入: 完整的 UDS 请求报文 (已剥离传输层,仅应用层数据)
// 输出: 响应报文 (肯定或否定)
std::vector handleReadDataByIdentifier(const std::vector& request, const DidStorage& storage) {
// 最小请求长度: 1字节SID + 2字节DID = 3
if (request.size() < 3 || request[0] != 0x22) {
// 格式错误或非0x22服务 -> 返回 NRC 0x13 (消息长度/格式错误)
return {0x7F, 0x22, 0x13};
}

// 目前仅实现单个 DID 读取 (多DID处理原理相同,可循环)
if (request.size() == 3) {
uint16_t did = (static_cast(request[1]) << 8) | request[2];
const auto* data = storage.getData(did);
if (data == nullptr) {
// DID 不支持 -> NRC 0x31 (请求超出范围)
return {0x7F, 0x22, 0x31};
}
// 构造肯定响应: 0x62 + DID(2B) + data
std::vector response;
response.reserve(3 + data->size());
response.push_back(0x62);
response.push_back(static_cast((did >> 8) & 0xFF));
response.push_back(static_cast(did & 0xFF));
response.insert(response.end(), data->begin(), data->end());
return response;
}
else {
// 请求报文长度 >3 意味着多个 DID,本例简化处理,返回 NRC 0x14 (数据太长)
// 实际产品应解析多个 DID 并按顺序拼接数据
return {0x7F, 0x22, 0x14};
}
}

// 辅助打印函数
void printHex(const std::vector& data, const std::string& desc) {
std::cout << desc << " [";
for (size_t i = 0; i < data.size(); ++i) {
std::cout << std::hex << std::uppercase << static_cast(data[i]);
if (i != data.size() - 1) std::cout << " ";
}
std::cout << std::dec << "]" << std::endl;
}

int main() {
// 初始化 ECU 数据存储区
DidStorage ecuStorage;

// 测试场景1: 有效单个 DID (0xF18C)
std::vector request1 = {0x22, 0xF1, 0x8C};
auto response1 = handleReadDataByIdentifier(request1, ecuStorage);
printHex(response1, "Request: 22 F1 8C -> Response");

// 测试场景2: 有效单个 DID (0x1000 里程)
std::vector request2 = {0x22, 0x10, 0x00};
auto response2 = handleReadDataByIdentifier(request2, ecuStorage);
printHex(response2, "Request: 22 10 00 -> Response");

// 测试场景3: 不支持的 DID (0x9999)
std::vector request3 = {0x22, 0x99, 0x99};
auto response3 = handleReadDataByIdentifier(request3, ecuStorage);
printHex(response3, "Request: 22 99 99 -> Response");

// 测试场景4: 格式错误 (长度不足)
std::vector request4 = {0x22, 0xF1};
auto response4 = handleReadDataByIdentifier(request4, ecuStorage);
printHex(response4, "Request: 22 F1 (too short) -> Response");

return 0;
}
4.3 代码运行结果

Request: 22 F1 8C -> Response [62 F1 8C 53 4E 30 30 31 32 33 34]
Request: 22 10 00 -> Response [62 10 00 34 12 0 0]
Request: 22 99 99 -> Response [7F 22 31]
Request: 22 F1 (too short) -> Response [7F 22 13]
4.4 代码说明
  1. DidStorage 类:模拟 ECU 内部的非易失/易失数据字典,使用std::map > 存储。

  2. handleReadDataByIdentifier:

  • 首先校验请求长度及 SID。

  • 提取第一个 DID(本例为简化,只处理单 DID)。

  • 调用storage.getData查询数据。

  • 若找到则构造0x62 + DID + Data的肯定响应。

  • 若找不到返回 NRC 0x31。

多 DID 支持:标准 UDS 允许一次请求多个 DID,响应应顺序返回每个 DID 及其数据。本示例为简洁未实现,但可以扩展:循环解析每个 DID,依次查表,将结果拼接进响应;若任何一个 DID 无效,则中止并返回 NRC 0x31。

传输层:实际车辆中,UDS 报文可能大于 8 字节(如 VIN 的 17 字节),需要底层协议如 ISO 15765-2 (CAN-TP) 进行拆包。本例假设请求/响应长度均 ≤ 8 字节,聚焦服务逻辑。

5. 实际开发注意事项

  • 安全性:某些 DID 读取需要先通过安全访问(0x27 服务),否则应返回 NRC 0x22。

  • 动态数据:里程、电压等 DID 应在读取时实时从硬件获取,而不是返回静态缓存值。

  • 字节序:多字节数值(如 int32)在 CAN 总线通常采用大端(Motorola)或小端(Intel)。需与 OEM 保持一致,本示例中里程按小端存储。

  • 扩展多 DID:请求22 F1 8C F1 90,响应应为62 F1 8C F1 90 。

  • NRC 优先级:若同时存在多个错误(如长度错误且 DID 不支持),应优先返回格式类 NRC(0x13)。

6. 总结

UDS 0x22 服务是诊断交互中最基础也最实用的服务之一,让外部工具轻松读取出 ECU 内部的各种标识数据。通过合理设计 DID 表,可以覆盖从静态标定信息到实时物理量的全部读取需求。开发者实现时需注意:

  • 正确解析 DID

  • 处理不支持 DID 情况

  • 考虑数据长度和传输协议

  • 必要时加入安全访问保护敏感数据

以上代码示例可以直接集成到 ECU 诊断栈的对应服务回调中,作为开发参考。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
教育部原党组成员、副部长鲁昕被查

教育部原党组成员、副部长鲁昕被查

都市快报橙柿互动
2026-09-28 10:17:29
广东一租客因欠租搬走后,13岁男孩被独留停水停电出租屋不上学:母亲拒绝帮助,父亲电话停机;房东急了

广东一租客因欠租搬走后,13岁男孩被独留停水停电出租屋不上学:母亲拒绝帮助,父亲电话停机;房东急了

扬子晚报
2026-09-28 10:28:50
耿同学又出手!揭《Nature》一论文造假,24个原始值完全一致,通讯作者已承认并撤稿

耿同学又出手!揭《Nature》一论文造假,24个原始值完全一致,通讯作者已承认并撤稿

材料科学与工程
2026-09-24 11:48:39
女子千里赴约让情人白睡,2016年情夫和她缠绵完很满足,将她杀死并抛尸

女子千里赴约让情人白睡,2016年情夫和她缠绵完很满足,将她杀死并抛尸

汉史趣闻
2026-09-26 09:25:49
亚运会:世界第1爆冷出局!冯彦哲/黄东萍0-2印尼混双,5连胜终结

亚运会:世界第1爆冷出局!冯彦哲/黄东萍0-2印尼混双,5连胜终结

钉钉陌上花开
2026-09-28 09:13:11
主张联俄抗中的专家叛变了!去俄罗斯待了7天,回来就换了说法

主张联俄抗中的专家叛变了!去俄罗斯待了7天,回来就换了说法

游文刀
2026-09-24 21:18:36
这跟不穿有啥区别?三角区明显,41岁女星穿透视3D打印裙惹争议

这跟不穿有啥区别?三角区明显,41岁女星穿透视3D打印裙惹争议

铁锤妹妹是只猫
2026-09-26 19:04:43
西贝又上热搜了,不是罗永浩,是俩探店博主线下吃出来的热度。

西贝又上热搜了,不是罗永浩,是俩探店博主线下吃出来的热度。

荆楚寰宇文枢
2026-09-27 20:53:44
再看刘欢的从头再来:为什么是普通工人而不是干部和领导?

再看刘欢的从头再来:为什么是普通工人而不是干部和领导?

阿废冷眼观察所
2026-09-27 16:01:39
塞尔维亚总统武契奇宣布辞职

塞尔维亚总统武契奇宣布辞职

澎湃新闻
2026-09-28 02:47:02
知名投资人曝刘欢真实死因是肝癌!8月底他曾在餐厅吃饭状态不错

知名投资人曝刘欢真实死因是肝癌!8月底他曾在餐厅吃饭状态不错

一个小豹子
2026-09-27 09:40:19
绝了!唐僧取经先被办证窗口问崩溃,教师资格证采矿证捕捞证一张不能少

绝了!唐僧取经先被办证窗口问崩溃,教师资格证采矿证捕捞证一张不能少

三言四拍
2026-09-27 19:24:04
王祉怡0-2不敌山口茜无缘亚运会女单决赛,收获铜牌

王祉怡0-2不敌山口茜无缘亚运会女单决赛,收获铜牌

懂球帝
2026-09-28 12:12:06
创业板指跌逾2%,全市场下跌个股超4200只

创业板指跌逾2%,全市场下跌个股超4200只

界面新闻
2026-09-28 09:39:39
七连斩世界第5!刘圣书/谭宁2-1逆转大马王牌,剑指亚运女双首冠

七连斩世界第5!刘圣书/谭宁2-1逆转大马王牌,剑指亚运女双首冠

钉钉陌上花开
2026-09-28 10:06:57
伊朗总统当着美媒面诉苦:石油卖给中国,钱却卡在账户里

伊朗总统当着美媒面诉苦:石油卖给中国,钱却卡在账户里

共工之锚
2026-09-28 00:20:41
C罗暴怒原因揭晓!约好出战半小时却变卦 72岁新帅:他不该拒绝谢场

C罗暴怒原因揭晓!约好出战半小时却变卦 72岁新帅:他不该拒绝谢场

我爱英超
2026-09-28 07:14:39
陈圆将造世界名画:夺金后霸气庆祝 赛前无视他的日本选手绝望跪地

陈圆将造世界名画:夺金后霸气庆祝 赛前无视他的日本选手绝望跪地

风过乡
2026-09-28 07:37:22
穆里尼奥狂喜!皇马天降超级喜讯!巴萨这下要慌了

穆里尼奥狂喜!皇马天降超级喜讯!巴萨这下要慌了

澜归序
2026-09-28 08:25:24
李克勤演唱会迟到,救场歌手连唱近20首,本人表示:“3万人的演出这还是第一次,之前最多是五六千人”

李克勤演唱会迟到,救场歌手连唱近20首,本人表示:“3万人的演出这还是第一次,之前最多是五六千人”

韩小娱
2026-09-27 16:58:06
2026-09-28 12:36:49
新能源自动驾驶 incentive-icons
新能源自动驾驶
专注于半导体行业资讯
1015文章数 348关注度
往期回顾 全部

科技要闻

智能体惹了多少祸,OpenAI自己没查清!

头条要闻

媒体:俄杜马选举普京获压倒性胜利 俄乌冲突有2大走向

头条要闻

媒体:俄杜马选举普京获压倒性胜利 俄乌冲突有2大走向

体育要闻

114项指控成立,曼城已经完蛋了吗?

娱乐要闻

好汉刘欢:一副好嗓子,一颗赤子心

财经要闻

标价298元核桃油, 实为大豆油冒充

汽车要闻

神龙科技与Momenta达成全球战略合作 2027年起推新车

态度原创

数码
家居
房产
健康
教育

数码要闻

满电青春集结古都 航嘉满电青年计划9月22日登陆西安电子科技大学

家居要闻

2026建博会(广州) 公装联探展交流活动

房产要闻

全年霸榜TOP1!南海・叁號院周年官宣:新作即将登场

鼻子三角区的痘,千万别乱挤!

教育要闻

一个家庭,父母越“尊重”孩子,孩子脾气越大……

无障碍浏览 进入关怀版