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

UDS诊断服务详解:上传下载功能单元(0x34/0x35/0x36/0x37)及C++实现

0
分享至


在汽车电子诊断领域,UDS(Unified Diagnostic Services,统一诊断服务)是ISO 14229标准定义的一套通用诊断协议。其中“上传下载功能单元”(Upload Download functional unit)用于在诊断工具(Tester)与ECU之间传输大量数据,例如固件升级、标定数据读取/写入、配置备份恢复等。该单元包含四个核心服务:

  • 0x34 RequestDownload(请求下载)

  • 0x35 RequestUpload(请求上传)

  • 0x36 TransferData(传输数据)

  • 0x37 RequestTransferExit(请求传输退出)

本文将逐一讲解这些服务的报文格式、通信流程,并给出基于C++的简化实现示例,帮助开发者快速集成到诊断工具或自动化测试脚本中。

一、UDS基础回顾

UDS基于客户端-服务器模型,诊断工具作为客户端(Tester),ECU作为服务器。所有请求/响应报文均遵循统一的寻址和子功能定义。传输层通常使用CAN(ISO 15765)、LIN或以太网(DoIP)。

上传下载功能单元在设计上考虑了可靠性、流控和分段传输,尤其适合传输超过单帧报文长度的数据。

二、服务详解 1. 0x34 RequestDownload(请求下载)

用途:客户端通知ECU即将开始数据下载(即向ECU写入数据),并告知数据长度和起始地址等信息。ECU回应其可以接收的最大数据长度(每块大小)。

请求报文格式(以CAN/CAN FD为例):

字节位置

参数名

0

0x34

服务ID

1

数据格式标识(dataFormatIdentifier)

通常为0x00,表示未压缩、未加密

地址和长度信息(addressAndLengthFormatIdentifier)

高4位:内存地址字节数;低4位:数据长度字节数

内存地址(memoryAddress)

可变字节(由前述高4位决定)

数据长度(memorySize)

可变字节(由前述低4位决定)

响应报文(肯定响应):

字节位置

参数名

0

0x74

服务ID + 0x40

1

数据格式标识(echo)

回显请求中的值

maxNumberOfBlockLength

每块传输的最大数据字节数(3字节)

注意:ECU会校验请求中的地址/长度是否合法,若无法满足则返回否定响应(例如NRC 0x31 RequestOutOfRange)。

2. 0x35 RequestUpload(请求上传)

用途:客户端请求从ECU上传数据(即读取ECU内存)。其报文结构类似于RequestDownload,区别在于服务ID和语义。

请求报文格式

字节

内容

0

0x35

1

数据格式标识

2

地址+长度格式标识

内存地址(起始地址)

数据长度(要读取的字节数)

肯定响应

字节

内容

0

0x75

1

数据格式标识(echo)

maxNumberOfBlockLength(每块能返回的最大字节数)


3. 0x36 TransferData(传输数据)

用途:真正承载数据块。下载时客户端发送数据给ECU;上传时ECU返回数据给客户端。通过多次调用0x36服务完成全部数据传送。

请求报文格式(下载方向):

字节

内容

0

0x36

1

blockSequenceCounter(块序列计数器,0x01开始,循环使用0x00~0xFF)

数据字节(长度 ≤ maxNumberOfBlockLength)

响应报文(下载时ECU回复):

字节

内容

0

0x76

1

blockSequenceCounter(回显请求中的计数)

对于上传方向,客户端发送0x36请求(仅带序列计数器,无数据载荷),ECU在响应中携带数据。

4. 0x37 RequestTransferExit(请求传输退出)

用途:在所有数据块传输完成后,客户端发送此服务通知ECU传输结束,ECU进行完整性校验或关闭会话上下文。

请求报文

字节

内容

0

0x37

肯定响应:0x77

三、典型通信流程(以下载为例)

  1. 进入扩展会话(可选但推荐):使用0x10服务切换至编程会话,并解锁安全访问(0x27服务)获得写入权限。

  2. 发送RequestDownload:告知起始地址(例如0x8000)和数据总长度(4096字节)。ECU回复允许的块大小(如256字节)。

  3. 循环发送TransferData:将4096字节拆分为16块(每块256字节),每块发送一条0x36服务(块计数递增)。ECU每块回复0x76确认。

  4. 发送RequestTransferExit:通知ECU传输结束。ECU回复0x77。

  5. 执行完整性校验或复位(可选)。

四、C++实现讲解

下面给出一个简化的C++类,模拟诊断工具侧对上述服务的封装。实际项目中会依赖硬件通信库(如CAN卡API),此处用抽象接口表示发送/接收。

1. 基础诊断通信接口

// DiagnosticChannel.h - 抽象传输层
class DiagnosticChannel {
public:
virtual ~DiagnosticChannel() = default;
virtual std::vector request(const std::vector& requestData) = 0;
// 底层需处理ISO-TP分段、流控和超时
};
2. 上传下载功能类

#include  

#include
#include

class UploadDownloadService {
public:
UploadDownloadService(DiagnosticChannel* channel) : m_channel(channel) {}

// 请求下载
bool requestDownload(uint32_t memoryAddress, uint32_t memorySize,
uint16_t& maxBlockSize) {
// 构建请求 (简化:固定地址长度4字节,数据长度4字节)
std::vector request;
request.push_back(0x34); // SID
request.push_back(0x00); // dataFormatIdentifier
request.push_back(0x44); // addressAndLengthFormat: 地址4字节,长度4字节
// 内存地址 (大端)
request.push_back((memoryAddress >> 24) & 0xFF);
request.push_back((memoryAddress >> 16) & 0xFF);
request.push_back((memoryAddress >> 8) & 0xFF);
request.push_back(memoryAddress & 0xFF);
// 数据长度 (大端)
request.push_back((memorySize >> 24) & 0xFF);
request.push_back((memorySize >> 16) & 0xFF);
request.push_back((memorySize >> 8) & 0xFF);
request.push_back(memorySize & 0xFF);

auto response = m_channel->request(request);
if (response.empty() || response[0] != 0x74) {
return false; // 处理否定响应可细化NRC
}
// 解析 maxNumberOfBlockLength (3字节,大端)
if (response.size() >= 5) {
maxBlockSize = (response[2] << 16) | (response[3] << 8) | response[4];
}
return true;
}

// 传输单块数据 (下载方向)
bool transferData(uint8_t blockCounter, const std::vector& data) {
std::vector request;
request.push_back(0x36);
request.push_back(blockCounter);
request.insert(request.end(), data.begin(), data.end());

auto response = m_channel->request(request);
return (!response.empty() && response[0] == 0x76 && response[1] == blockCounter);
}

// 请求退出传输
bool requestTransferExit() {
std::vector request = {0x37};
auto response = m_channel->request(request);
return (!response.empty() && response[0] == 0x77);
}

// 高级封装:下载完整数据
bool downloadData(uint32_t address, const std::vector& data) {
uint16_t maxBlockSize = 0;
if (!requestDownload(address, static_cast(data.size()), maxBlockSize)) {
return false;
}
if (maxBlockSize == 0) return false;

uint8_t counter = 1;
size_t offset = 0;
while (offset < data.size()) {
size_t chunkSize = std::min(maxBlockSize, static_cast(data.size() - offset));
std::vector chunk(data.begin() + offset, data.begin() + offset + chunkSize);
if (!transferData(counter++, chunk)) {
return false;
}
offset += chunkSize;
}
return requestTransferExit();
}

private:
DiagnosticChannel* m_channel;
};
3. 上传功能类似实现

上传的流程中,transferData请求不带数据,而是从响应中提取数据块:

// 上传功能扩展
std::vector uploadData(uint32_t address, uint32_t size) {
std::vector result;
// 1. RequestUpload ...
// 2. 循环发送TransferData (不带数据载荷)
// 3. 从响应中获取数据并拼接
// 4. RequestTransferExit
// 代码模式类似download,这里省略详细实现
return result;
}
4. 集成到实际通信通道示例

使用SocketCAN(Linux)的伪代码:

class SocketCANChannel : public DiagnosticChannel {
int sock;
public:
std::vector request(const std::vector& req) override {
// 使用ISO-TP协议封装CAN帧 (需分段发送)
// 接收完整响应,处理流控帧
// ...
return response;
}
};
五、注意事项与最佳实践
  1. 地址和长度格式协商addressAndLengthFormatIdentifier需与ECU文档严格匹配。不同ECU可能使用2字节地址+2字节长度等。

  2. 块序列计数器:应从0x01开始,循环使用,但传输完成前不应重复。部分ECU对乱序敏感。

  3. 错误处理:处理否定响应码(NRC),常见的有:

  • 0x13:incorrectMessageLength

  • 0x22:conditionsNotCorrect(通常需要先进入编程会话)

  • 0x31:requestOutOfRange(地址或长度超限)

  • 0x70:uploadDownloadNotAccepted

安全访问:大多数ECU要求先通过0x27服务解锁权限,否则返回0x33 securityAccessDenied

传输中断恢复:如果某次TransferData失败,需要重新发起完整的下载流程(RequestDownload重新开始)。不支持断点续传(除非应用层自定义)。

时序和流控:在CAN上使用ISO-TP时,ECU会通过流控帧控制发送节奏,底层通道必须正确处理。

六、总结

UDS上传下载功能单元(0x34~0x37)为ECU编程和标定提供了标准化的数据块传输机制。理解这四个服务的交互时序及其C++封装,能够帮助开发者快速构建诊断刷写工具。在实际项目中,还需结合具体的传输层(如DoIP、CAN-FD)和安全机制(TLS、SecOC)。通过本文的示例代码,读者可以基于自己的通信框架进行扩展,实现可靠的固件升级和诊断数据采集。

扩展阅读:ISO 14229-1:2020 标准第6章(UploadDownload functional unit)、ISO 15765-2(传输层)

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

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-06-01 20:09:42
大满贯8连胜终结!张帅0-2输德比:无缘法网8强,进账85万奖金!

大满贯8连胜终结!张帅0-2输德比:无缘法网8强,进账85万奖金!

刘姚尧的文字城堡
2026-06-02 07:48:16
结束访华不到20天,特朗普紧急下禁令,要斩断中国“经济命脉”?

结束访华不到20天,特朗普紧急下禁令,要斩断中国“经济命脉”?

傲傲讲历史
2026-06-02 11:48:57
寿命长不长,看脸就知道?寿命短的人,脸上一般会有这5个特征!

寿命长不长,看脸就知道?寿命短的人,脸上一般会有这5个特征!

芹姐说生活
2026-06-02 23:16:44
阿迪达斯发进城办事T恤,客服回应

阿迪达斯发进城办事T恤,客服回应

第一财经资讯
2026-06-02 15:07:57
反套路超英登顶!尼古拉斯·凯奇新剧凭什么取代《黑袍纠察队》

反套路超英登顶!尼古拉斯·凯奇新剧凭什么取代《黑袍纠察队》

追星雷达站
2026-06-02 01:50:59
不出 5 年,中国贬值最快的不是房子和现金,而是这 3 样东西

不出 5 年,中国贬值最快的不是房子和现金,而是这 3 样东西

细说职场
2026-04-26 21:04:20
河南一足疗店推出“反方向按摩”,花200多给女技师洗脚70分钟

河南一足疗店推出“反方向按摩”,花200多给女技师洗脚70分钟

汉史趣闻
2026-06-02 11:04:59
2006年,它发誓砍掉所有USB线,然后三年就凉透了

2006年,它发誓砍掉所有USB线,然后三年就凉透了

Ping值焦虑
2026-06-01 01:58:28
欧冠决赛惊现最孤独座位,哈维惊喜现身送温暖

欧冠决赛惊现最孤独座位,哈维惊喜现身送温暖

绿茵狂热者
2026-06-02 01:50:28
“都绝户了,还拼命挣钱干嘛?”看见父亲50岁就躺平,我崩溃了

“都绝户了,还拼命挣钱干嘛?”看见父亲50岁就躺平,我崩溃了

素十三儿
2026-04-13 07:12:36
英国遭到拒绝后发出警告,中国若不合作,中企海外资产将被没收!

英国遭到拒绝后发出警告,中国若不合作,中企海外资产将被没收!

冷眼看尽世间繁华
2026-04-05 03:49:18
主角大结局:胡三元花彩香结婚,刘红兵没死,封潇潇成武戏演员

主角大结局:胡三元花彩香结婚,刘红兵没死,封潇潇成武戏演员

八卦南风
2026-06-02 10:48:18
黄仁勋从口袋掏出RTX Spark,PC行业的“iPhone时刻”来了

黄仁勋从口袋掏出RTX Spark,PC行业的“iPhone时刻”来了

新京报
2026-06-02 12:16:41
七战全胜,狂轰21球,失2球,中国足球小将夺冠!赛后,董路发言

七战全胜,狂轰21球,失2球,中国足球小将夺冠!赛后,董路发言

开成运动会
2026-06-03 00:56:14
特朗普,开掉“不听话的情报头子”

特朗普,开掉“不听话的情报头子”

中国新闻周刊
2026-06-02 21:26:00
有情有义,姆巴佩和多名法国队员招呼安保官员一起和总统合影

有情有义,姆巴佩和多名法国队员招呼安保官员一起和总统合影

懂球帝
2026-06-03 02:36:18
76岁的万科创始人王石,最近彻底成了全网焦点。

76岁的万科创始人王石,最近彻底成了全网焦点。

梦录的西方史话
2026-04-23 14:36:39
我将担任市委书记,去参加同学聚会,做副县长的同学不停炫耀

我将担任市委书记,去参加同学聚会,做副县长的同学不停炫耀

乔生桂
2025-07-31 13:01:57
属鼠人,6月3日后,你要出“大问题”!不是小事,千万别不当回事

属鼠人,6月3日后,你要出“大问题”!不是小事,千万别不当回事

普陀动物世界
2026-06-03 02:02:35
2026-06-03 04:00:49
新能源自动驾驶 incentive-icons
新能源自动驾驶
专注于半导体行业资讯
990文章数 348关注度
往期回顾 全部

汽车要闻

星途神秘新车轮廓曝光 又一款性能SUV要来了?

头条要闻

演员魏宗万去世 曾在94版《三国演义》中饰演"司马懿"

头条要闻

演员魏宗万去世 曾在94版《三国演义》中饰演"司马懿"

体育要闻

1米74的业余联赛替补,在英超踢中卫

娱乐要闻

奚梦瑶何猷君补办婚礼超幸福

财经要闻

智元和宇树的“暗战”愈演愈烈

科技要闻

烧掉千亿后,美团、阿里、京东谁先止血?

态度原创

手机
数码
旅游
亲子
军事航空

手机要闻

华为畅享100 Pro Max被曝立项:代号叶问,真的要打十个了!

数码要闻

苹果watchOS 27前瞻:改进心率追踪、引入新表盘、升级Siri

旅游要闻

北京位列全球数字旅游引领型城市榜首

亲子要闻

《前面有多生气,后面就有多搞笑》

军事要闻

伊朗媒体新发布最高领袖照片

无障碍浏览 进入关怀版