结合diag_subsystem_service.cpp理解UDS中DID与子功能的区别

结合全套代码,彻底讲清:

DID(数据标识符) vs 子功能(SubFunction) 的区别


核心结论(必须背下来)

DID = 你要操作【哪个功能/哪块数据】

子功能 = 你要对它【做什么动作】


用代码里的真实例子:2F D134 03

2F D134 03

写指令 DID 子功能

  • D134(DID) = 我要操作【离线安装】这个功能
  • 03(子功能) = 我要【启动】它

一、逐字逐句讲清楚(结合你的代码)

1. DID 是什么?(你代码里的定义)

DID = Data Identifier 数据标识符
作用:定位目标 → 告诉ECU:我要找谁?

在你的代码里:

if (did == DID_D134) {  // DID = 目标
    处理离线安装相关逻辑
}

DID 就像:

  • 房间号
  • 设备名
  • 功能模块
  • 数据编号

你代码里的 DID 用途:

  • D134 → 离线安装/远程安装模块
  • Dxxx → 版本号
  • Dxxx → 电压
  • Dxxx → 状态

DID 只决定:你找哪个对象,不决定做什么。


2. 子功能是什么?(SubFunction)

子功能 = 对DID执行的操作类型
作用:动作指令 → 告诉ECU:要做什么?

在你的代码里:

if (sub_srv == 0x03) {  // 子功能 = 动作
    启动离线安装
}

子功能就像:

  • 启动
  • 停止
  • 查询
  • 复位
  • 解锁

子功能只决定:你要执行什么动作,不决定目标是谁。


二、用生活类比(秒懂)

DID = 电器设备

子功能 = 遥控器按钮

  • D134 = 空调
  • 01 = 开
  • 02 = 关
  • 03 = 调模式

那么:

  • 2F D134 01 = 打开空调
  • 2F D134 02 = 关闭空调
  • 2F D134 03 = 切换空调模式

三、回到你的代码:最清晰的对应关系

你的代码:

DiagSdmErrorCode DiagSubsystemService::Handle2FMessage(...)
{
    uint16_t did = msg->GetMsgDid();       // 1. 先找DID(目标)
    uint8_t sub_srv = msg->GetMsgSubService(); // 2. 再看子功能(动作)

    if (did == D134) {          // 目标:离线安装
        if (sub_srv == 0x03) {  // 动作:启动
            启动远程安装流程
        }
        if (sub_srv == 0x01) {  // 动作:停止
            停止安装
        }
        if (sub_srv == 0x02) {  // 动作:查询状态
            返回安装状态
        }
    }
}

结论:

DID 决定目标,子功能决定动作。


四、最关键:为什么要分 DID 和子功能?

1. DID = 唯一对象

一个DID对应一个功能/一个数据

  • D134 → 安装
  • D100 → 版本
  • D200 → 电压

2. 子功能 = 对该对象的多种操作

同一个DID,可以有多个子功能

  • 01 = 查询
  • 02 = 停止
  • 03 = 启动
  • 04 = 复位

3. 组合起来 = 完整指令

  • D134 + 03 = 启动安装
  • D134 + 01 = 查询安装状态
  • D134 + 02 = 停止安装

五、你最困惑的 2F D134 03 终极翻译

2F D134 03

  • 2F:我要写操作(控制命令)
  • D134:目标是【离线安装模块】
  • 03:动作是【启动】

人话翻译:

对【离线安装】执行【启动】动作


六、最终总结(最简单、最清晰)

DID:你要操作哪个功能/数据?(目标)

子功能:你要对它做什么?(动作)


你的代码里最经典的例子:

DID     = D134  → 离线安装模块
子功能  = 03    → 启动
指令    = 2F D134 03 → 启动离线安装

posted on 2026-01-12 10:09  四季萌芽V  阅读(114)  评论(0)    收藏  举报

导航