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

UDS 0x85和0x22服务原理及代码示例

0
分享至


1. 诊断故障码设置控制服务 (ControlDTCSetting, 0x85) 1.1 服务概述

诊断故障码设置控制服务(0x85)用于动态地启用或禁用ECU内部诊断故障码(DTC)的记录功能。该服务通常用于维修或测试场景,避免在特定操作(如刷写、标定)期间因非真实故障产生误报。

根据ISO 14229-1标准,本服务具备以下关键行为:

  • 抑制/恢复记录:通过子函数参数指示ECU停止或重新开始记录DTC。

  • 会话层时序影响:若当前会话模式下抑制了DTC记录,当会话层时序参数(如P2Server_max)超时导致ECU自动返回默认会话(Default Session,0x01),DTC记录应自动恢复。

  • 复位影响:ECU执行任何硬件复位(上电复位、外部复位等)后,DTC记录功能恢复为默认允许状态。

  • 与清除服务联动:当诊断仪发送ClearDiagnosticInformation(0x14)服务清除DTC时,ECU必须重新开启DTC记录(即使之前处于抑制状态)。

1.2 报文格式 1.2.1 请求报文

字节序号

参数名称

值(hex)

0

SID

0x85

服务标识符

1

sub-function

0x01–0x02

DTC设置类型:
0x01 = off(停止记录)
0x02 = on(开始记录)

2…n

可选参数(保留)

标准中通常无额外参数,部分OEM扩展使用


注意:子函数字节的高四位为suppressPosRspMsgIndicationBit(0x00表示需要正响应),低四位为实际控制类型。
1.2.2 正响应报文

字节序号

参数名称

值(hex)

0

SID + 0x40

0xC5

服务正响应标识符

1

sub-function

0x01或0x02

回显请求中的控制类型

2…n

可选参数

标准无后续数据


1.2.3 负响应报文

字节序号

参数名称

值(hex)

0

0x7F

0x7F

负响应标识符

1

SID

0x85

原始服务标识符

2

NRC

见下表

负响应码(Negative Response Code)

常用NRC:

NRC

含义

0x12

子函数不支持(sub-function无效)

0x13

请求报文长度错误

0x22

条件不满足(例如在非扩展会话下请求)

0x31

请求超出范围(参数错误)


2. 通过标识符读取数据服务 (ReadDataByIdentifier, 0x22) 2.1 服务概述

通过数据标识符(DID,Data Identifier)读取数据服务允许诊断仪从ECU的存储器中读取一个或多个指定DID对应的数据记录。DID为两个字节(0x0000–0xFFFF),由车厂定义。

标准支持单请求多DID,但多数实现仅支持单个DID。下文以单DID为例说明。

2.2 报文格式 2.2.1 请求报文

字节序号

参数名称

值(hex)

0

SID

0x22

服务标识符

1

DID 高字节

0x00–0xFF

数据标识符高位

2

DID 低字节

0x00–0xFF

数据标识符低位

3…n

后续DID(可选)

多DID时重复字节1-2


2.2.2 正响应报文

字节序号

参数名称

值(hex)

0

SID + 0x40

0x62

服务正响应标识符

1

DID 高字节

0x00–0xFF

回显请求中的DID高位

2

DID 低字节

0x00–0xFF

回显请求中的DID低位

3…m

数据记录

可变

该DID对应的数据值

m+1…n

下一个DID+数据

无(多DID时重复)

仅当请求多个DID时存在


2.2.3 负响应报文

字节序号

参数名称

值(hex)

0

0x7F

0x7F

负响应标识符

1

SID

0x22

原始服务标识符

2

NRC

见下表

负响应码

常用NRC:

NRC

含义

0x13

请求报文长度错误

0x14

数据标识符不支持

0x22

条件不满足

0x31

请求超出范围(DID有效但无法读取)


3. C++代码实现示例

以下代码模拟一个简化但符合UDS行为规范的ECU,实现了:

  • ControlDTCSetting(0x85) 服务。

  • ReadDataByIdentifier(0x22) 服务。

  • 与ClearDiagnosticInformation(0x14) 的联动。

  • 会话超时与复位后自动恢复DTC记录的逻辑(通过定时器和复位标志模拟)。

#include  

#include
#include
#include
#include
#include
#include

// ---------- 辅助工具函数 ----------
// 将字节向量打印为十六进制
void printHex(const std::vector& data, const std::string& prefix = "") {
std::cout << prefix;
for (uint8_t b : data) {
printf("%02X ", b);
}
std::cout << std::endl;
}

// ---------- UDS 服务定义 ----------
const uint8_t SID_CONTROL_DTC_SETTING = 0x85;
const uint8_t SID_READ_DATA_BY_IDENTIFIER = 0x22;
const uint8_t SID_CLEAR_DIAG_INFO = 0x14;

// 子函数定义 (ControlDTCSetting)
const uint8_t DTC_SETTING_OFF = 0x01;
const uint8_t DTC_SETTING_ON = 0x02;

// DID 定义(示例)
const uint16_t DID_VIN = 0xF190;
const uint16_t DID_SW_VERSION = 0xF187;
const uint16_t DID_ECU_SERIAL = 0xF1A0;

// 负响应码 (NRC)
const uint8_t NRC_SUB_FUNCTION_NOT_SUPPORTED = 0x12;
const uint8_t NRC_INCORRECT_MESSAGE_LEN = 0x13;
const uint8_t NRC_REQUEST_OUT_OF_RANGE = 0x31;
const uint8_t NRC_CONDITIONS_NOT_CORRECT = 0x22;
const uint8_t NRC_DATA_IDENTIFIER_NOT_SUPP = 0x14;

// 简单模拟ECU环境
class EcuSimulator {
public:
EcuSimulator() : dtcRecordingEnabled_(true), currentSession_(0x01) // 默认会话
{
// 初始化模拟数据
vin_ = "1HGCM82633A123456";
swVersion_ = "2.1.0";
ecuSerial_ = "ECU_ABC123";
}

// 接收诊断请求(完整CAN帧数据域),返回响应数据
std::vector handleRequest(const std::vector& request) {
if (request.empty()) return buildNegativeResponse(0x00, NRC_INCORRECT_MESSAGE_LEN);

uint8_t sid = request[0];
switch (sid) {
case SID_CONTROL_DTC_SETTING:
return handleControlDTCSetting(request);
case SID_READ_DATA_BY_IDENTIFIER:
return handleReadDataByIdentifier(request);
case SID_CLEAR_DIAG_INFO:
return handleClearDiagnosticInfo(request);
default:
return buildNegativeResponse(sid, NRC_REQUEST_OUT_OF_RANGE);
}
}

// 模拟ECU复位(例如调用此函数后恢复DTC记录)
void performReset() {
std::cout << "[ECU] Performing reset...\n";
dtcRecordingEnabled_ = true; // 复位后恢复DTC记录
// 可选:切换到默认会话
currentSession_ = 0x01;
}

// 模拟会话超时(例如长时间无请求自动调用此函数)
void sessionTimeout() {
if (currentSession_ != 0x01) {
std::cout << "[ECU] Session timeout, switching to default session (0x01)\n";
currentSession_ = 0x01;
dtcRecordingEnabled_ = true; // 根据标准,会话超时返回默认会话后应恢复DTC记录
}
}

// 获取当前DTC记录状态(供外部监控)
bool isDtcRecordingEnabled() const { return dtcRecordingEnabled_; }

private:
bool dtcRecordingEnabled_; // DTC记录使能标志
uint8_t currentSession_; // 当前会话(0x01=默认, 0x02=编程等)
// 模拟数据
std::string vin_;
std::string swVersion_;
std::string ecuSerial_;

// 构建负响应
std::vector buildNegativeResponse(uint8_t sid, uint8_t nrc) const {
return {0x7F, sid, nrc};
}

// 处理 0x85 ControlDTCSetting
std::vector handleControlDTCSetting(const std::vector& req) {
// 最小长度:SID(1) + sub-function(1) = 2
if (req.size() < 2) {
return buildNegativeResponse(SID_CONTROL_DTC_SETTING, NRC_INCORRECT_MESSAGE_LEN);
}

uint8_t subFunc = req[1];
// 低四位为控制类型,高四位为抑制正响应标志(本例忽略抑制标志)
uint8_t controlType = subFunc & 0x0F;

// 可选:检查会话条件(例如只在扩展会话下允许)
if (currentSession_ != 0x02) { // 假设0x02为扩展诊断会话
return buildNegativeResponse(SID_CONTROL_DTC_SETTING, NRC_CONDITIONS_NOT_CORRECT);
}

bool newState;
switch (controlType) {
case DTC_SETTING_OFF:
newState = false;
break;
case DTC_SETTING_ON:
newState = true;
break;
default:
return buildNegativeResponse(SID_CONTROL_DTC_SETTING, NRC_SUB_FUNCTION_NOT_SUPPORTED);
}

dtcRecordingEnabled_ = newState;
std::cout << "[ECU] DTC recording has been " << (dtcRecordingEnabled_ ? "ENABLED" : "DISABLED")
<< " via 0x85 service.\n";

// 正响应:0xC5 + sub-function(原样返回)
return {static_cast(SID_CONTROL_DTC_SETTING + 0x40), subFunc};
}

// 处理 0x22 ReadDataByIdentifier
std::vector handleReadDataByIdentifier(const std::vector& req) {
// 最小长度:SID(1) + DID(2) = 3
if (req.size() < 3) {
return buildNegativeResponse(SID_READ_DATA_BY_IDENTIFIER, NRC_INCORRECT_MESSAGE_LEN);
}

uint16_t did = (static_cast(req[1]) << 8) | req[2];
std::vector data;

// 根据DID获取数据
if (did == DID_VIN) {
data.assign(vin_.begin(), vin_.end());
} else if (did == DID_SW_VERSION) {
data.assign(swVersion_.begin(), swVersion_.end());
} else if (did == DID_ECU_SERIAL) {
data.assign(ecuSerial_.begin(), ecuSerial_.end());
} else {
return buildNegativeResponse(SID_READ_DATA_BY_IDENTIFIER, NRC_DATA_IDENTIFIER_NOT_SUPP);
}

// 正响应:0x62 + DID + 数据
std::vector response;
response.push_back(SID_READ_DATA_BY_IDENTIFIER + 0x40);
response.push_back(req[1]); // DID高字节
response.push_back(req[2]); // DID低字节
response.insert(response.end(), data.begin(), data.end());
return response;
}

// 处理 0x14 ClearDiagnosticInformation
std::vector handleClearDiagnosticInfo(const std::vector& req) {
// 标准中0x14可能携带清除范围参数,此处简化:清除所有DTC并重新开启记录
// 实际实现中应真正清除存储的DTC列表
std::cout << "[ECU] Clearing all DTCs and re-enabling DTC recording.\n";
dtcRecordingEnabled_ = true; // 清除后必须恢复记录
// 正响应:0x54 (SID+0x40)
return {static_cast(SID_CLEAR_DIAG_INFO + 0x40)};
}
};

// ---------- 演示示例 ----------
int main() {
EcuSimulator ecu;

// 初始化:DTC记录默认开启
std::cout << "Initial DTC recording state: " << (ecu.isDtcRecordingEnabled() ? "Enabled" : "Disabled") << "\n\n";

// 模拟诊断仪发送 0x85 请求(停止记录)
std::vector req85_off = {0x85, 0x01}; // sub-function 0x01 = off
std::cout << "Request 0x85 (stop DTC recording): ";
printHex(req85_off);
auto resp85_off = ecu.handleRequest(req85_off);
printHex(resp85_off, "Response: ");
std::cout << "DTC recording state after request: " << (ecu.isDtcRecordingEnabled() ? "Enabled" : "Disabled") << "\n\n";

// 尝试读取一个DID(VIN)
std::vector req22_vin = {0x22, 0xF1, 0x90};
std::cout << "Request 0x22 (read VIN): ";
printHex(req22_vin);
auto resp22_vin = ecu.handleRequest(req22_vin);
printHex(resp22_vin, "Response: ");
std::string vinStr(resp22_vin.begin() + 3, resp22_vin.end());
std::cout << "VIN: " << vinStr << "\n\n";

// 模拟会话超时(应自动恢复DTC记录)
std::cout << "Simulating session timeout...\n";
ecu.sessionTimeout();
std::cout << "DTC recording state after timeout: " << (ecu.isDtcRecordingEnabled() ? "Enabled" : "Disabled") << "\n\n";

// 模拟ECU复位
std::cout << "Simulating ECU reset...\n";
ecu.performReset();
std::cout << "DTC recording state after reset: " << (ecu.isDtcRecordingEnabled() ? "Enabled" : "Disabled") << "\n\n";

// 模拟发送 0x14 清除诊断信息
std::vector req14 = {0x14, 0xFF, 0xFF}; // 简化的清除所有DTC
std::cout << "Request 0x14 (clear DTCs): ";
printHex(req14);
auto resp14 = ecu.handleRequest(req14);
printHex(resp14, "Response: ");
std::cout << "DTC recording state after clear: " << (ecu.isDtcRecordingEnabled() ? "Enabled" : "Disabled") << "\n\n";

return 0;
}
3.1 代码说明
  1. EcuSimulator类:

  • dtcRecordingEnabled_标志位模拟DTC记录状态。

  • handleControlDTCSetting:检查会话条件(要求扩展会话0x02),修改标志位,返回0xC5+子函数。

  • handleReadDataByIdentifier:支持三个示例DID,返回ASCII字符串数据。

  • handleClearDiagnosticInfo:模拟清除所有DTC,并将dtcRecordingEnabled_强制置为true。

会话超时与复位:

  • sessionTimeout():将当前会话切回默认会话(0x01),同时恢复DTC记录。

  • performReset():模拟硬件复位,恢复DTC记录。

符合标准的行为:

  • 0x85请求中若子函数无效返回NRC 0x12。

  • 非扩展会话下执行0x85返回NRC 0x22(条件不满足)。

  • 0x14服务后自动使能记录。

3.2 运行输出示例

Initial DTC recording state: Enabled

Request 0x85 (stop DTC recording): 85 01
[ECU] DTC recording has been DISABLED via 0x85 service.
Response: C5 01
DTC recording state after request: Disabled

Request 0x22 (read VIN): 22 F1 90
Response: 62 F1 90 31 48 47 43 4D 38 32 36 33 33 41 31 32 33 34 35 36
VIN: 1HGCM82633A123456

Simulating session timeout...
[ECU] Session timeout, switching to default session (0x01)
DTC recording state after timeout: Enabled

Simulating ECU reset...
[ECU] Performing reset...
DTC recording state after reset: Enabled

Request 0x14 (clear DTCs): 14 FF FF
[ECU] Clearing all DTCs and re-enabling DTC recording.
Response: 54
DTC recording state after clear: Enabled
4. 总结

本文详细解析了UDS服务ControlDTCSetting(0x85) 和ReadDataByIdentifier(0x22) 的协议格式、行为约束,并通过C++代码给出了符合ISO 14229-1规范的实现示例。实际量产ECU中还需考虑多DID读取、安全访问、DTC存储管理等额外功能,但上述代码清晰展示了核心流程与标准要求的关键交互行为。

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

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.

相关推荐
热点推荐
张雪一句“鄙视你”,泰康秒赔8万:他不是突然良心发现,而是突然发现“不要脸的成本”太高了

张雪一句“鄙视你”,泰康秒赔8万:他不是突然良心发现,而是突然发现“不要脸的成本”太高了

迷世书童
2026-09-27 10:52:03
医院老护士含泪揭秘:人临终前的10个残酷真相,很多子女不懂

医院老护士含泪揭秘:人临终前的10个残酷真相,很多子女不懂

蝉吟槐蕊
2026-09-13 18:15:04
25岁女子吐槽河北婆婆做“糊弄饭”,老公不耐烦了:爱吃吃不吃滚

25岁女子吐槽河北婆婆做“糊弄饭”,老公不耐烦了:爱吃吃不吃滚

许三岁
2026-09-28 02:00:08
小布披露绝望输球内幕下周取代吴易昺,王左亚运血案含金量引热议

小布披露绝望输球内幕下周取代吴易昺,王左亚运血案含金量引热议

网球之家
2026-09-28 10:27:54
低价“0公里二手车”连环骗局爆雷,上千车主或面临钱车两空

低价“0公里二手车”连环骗局爆雷,上千车主或面临钱车两空

凤凰网财经
2026-09-27 22:01:48
4次扑救哈兰德+非常规手型!科斯塔9.4分,葡萄牙换代成功了

4次扑救哈兰德+非常规手型!科斯塔9.4分,葡萄牙换代成功了

赵或是个热血青年
2026-09-28 11:28:49
西方不服气,为何中国没发动任何战争,却成为世界一流经济强国

西方不服气,为何中国没发动任何战争,却成为世界一流经济强国

纪史行者
2026-09-28 08:33:10
刘欢临终细节被曝!含泪离世,老婆女儿都守在身旁,母女俩太痛苦

刘欢临终细节被曝!含泪离世,老婆女儿都守在身旁,母女俩太痛苦

观察鉴娱
2026-09-27 10:19:27
张杰谢娜一家五口出游,仨女儿都坐推车不带腿,有专属摄影师摄像

张杰谢娜一家五口出游,仨女儿都坐推车不带腿,有专属摄影师摄像

阿废冷眼观察所
2026-09-28 00:02:06
喜讯!U23国足进入亚运会四强之后,足协就可能跟多位强援完成续约

喜讯!U23国足进入亚运会四强之后,足协就可能跟多位强援完成续约

振刚说足球
2026-09-28 10:05:42
亚运会女单金牌得主诞生!王曼昱4-2险胜孙颖莎,摘得生涯第2冠

亚运会女单金牌得主诞生!王曼昱4-2险胜孙颖莎,摘得生涯第2冠

乒谈
2026-09-27 20:58:07
彻底崩盘!曼联 6000 万水货混日子!名宿怒喷卡里克赶紧清洗

彻底崩盘!曼联 6000 万水货混日子!名宿怒喷卡里克赶紧清洗

澜归序
2026-09-28 09:11:57
人无法共情以前自己买的那些东西。网友:三个垃圾桶1700。

人无法共情以前自己买的那些东西。网友:三个垃圾桶1700。

天气观察站
2026-09-27 16:03:26
气愤!刘翔师弟夺冠后怒斥:日本电视台没把我当回事 日本选手无视我

气愤!刘翔师弟夺冠后怒斥:日本电视台没把我当回事 日本选手无视我

念洲
2026-09-27 20:49:20
李谷一不再隐瞒,揭晓宋祖英走上高位的真相,观众:原来如此!

李谷一不再隐瞒,揭晓宋祖英走上高位的真相,观众:原来如此!

林轻吟
2026-07-02 19:19:19
中秋假期游客在秦皇岛乘坐海上索道被淋成落汤鸡,景区:下雨后暂停了一会索道,淋到雨的游客是在下雨前上去的

中秋假期游客在秦皇岛乘坐海上索道被淋成落汤鸡,景区:下雨后暂停了一会索道,淋到雨的游客是在下雨前上去的

台州交通广播
2026-09-27 19:31:25
一投提前下班!严子怡大幅提升赛会纪录,夺亚运会女子标枪金牌

一投提前下班!严子怡大幅提升赛会纪录,夺亚运会女子标枪金牌

全景体育V
2026-09-27 21:01:43
如果莉莉贝特真长这样!丝毫不输夏洛特公主,皮肤还更白嫩!

如果莉莉贝特真长这样!丝毫不输夏洛特公主,皮肤还更白嫩!

艺利森
2026-09-28 09:07:46
美方同意放行伊朗总统,专机起飞后怕生变故,全程未在第三国停靠

美方同意放行伊朗总统,专机起飞后怕生变故,全程未在第三国停靠

你是我心中最美星空
2026-09-27 20:36:09
案例:湖南女护士被执行死刑,行刑时回头质问武警,让他当场崩溃

案例:湖南女护士被执行死刑,行刑时回头质问武警,让他当场崩溃

星宇共鸣
2025-09-17 17:58:03
2026-09-28 12:08:49
新能源自动驾驶 incentive-icons
新能源自动驾驶
专注于半导体行业资讯
1015文章数 348关注度
往期回顾 全部

科技要闻

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

头条要闻

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

头条要闻

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

体育要闻

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

娱乐要闻

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

财经要闻

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

汽车要闻

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

态度原创

艺术
时尚
房产
亲子
本地

艺术要闻

致敬,刘欢硬笔书法欣赏

女人过了三四十岁,一定要准备一件小西装,大方得体又显瘦

房产要闻

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

亲子要闻

监控拍下拖把在锅里涮,老师辞职后才敢发图,孩子吐了没人当回事

本地新闻

中秋逛白塔寺,体验国医妙荟雅集

无障碍浏览 进入关怀版