Dcm 是 AUTOSAR Classic 中诊断通信的协议控制与服务编排中心:
- 向下承接 PduR 和 TP 层传入的完整 UDS/OBD 请求
- 在内部完成连接管理、会话和安全校验、服务分发与异步任务调度
- 向上调用 SWC、Dem、NvM、BswM、Csm、KeyM 等模块完成具体业务
- 最后组织肯定响应或否定响应,并通过 PduR 返回诊断仪
Dcm 不负责 CAN 分帧重组、不直接操作 CAN 控制器,也通常不持有具体业务数据。它处理的是完整诊断消息及其执行上下文,而底层 TP 负责 N-PDU 分段与重组,应用或其他 BSW 模块负责数据、故障、存储和硬件操作。

工作机制
内部分层
Dcm 内部可理解为三个层次:
DSL:连接、协议、缓冲区、收发、定时器、会话上下文
↓
DSD:识别 SID、验证权限、分发服务、组织最终响应
↓
DSP:执行具体 UDS/OBD 服务,调用 SWC 或其他 BSW从实现角度,Dcm 不是简单的“收到报文后调用一个函数”,而是一个以 Dcm_MainFunction 为节拍的事务执行器。
上层业务契约
对于 DID、RID 和安全访问,Dcm 通过生成回调或 RTE Mapping 调用应用:
- DID:
ReadData,WriteData,ConditionCheckRead - RID:
Start,Stop,RequestResult - Security:
GetSeed,CompareKey - 诊断服务与模式联动:Session Control、ECU Reset、Communication Control(分别涉及 Dcm 会话处理、EcuM 复位流程及 BswM/ComM 通信控制,并非同一种 AUTOSAR Mode-Switch 接口)
同步接口在本次调用中返回最终结果;配置为异步的接口首次以 DCM_INITIAL 调用,若返回 DCM_E_PENDING,Dcm 会在后续处理周期中以 DCM_PENDING 继续调用。应用回调应按操作状态区分首次执行、继续执行和取消处理,并避免重复执行不可重复的副作用。
下层输入契约
TP 通过以下回调把一个完整诊断 N-SDU 逐步交给 Dcm:
Dcm_StartOfReception- 告知总长度
- Dcm 检查初始化状态、PduId、Buffer 容量和忙闲状态
Dcm_CopyRxData- 分段把数据复制进 DSL Buffer
Dcm_TpRxIndication- 通知完整 N-SDU 接收成功或失败
接收完成前,Dcm 只是在填充缓冲区;只有收到成功的 Dcm_TpRxIndication 后,才可以开始处理请求。
下层输出契约
Dcm 组织响应后,通过 PduR 发起传输,TP 随后调用:
Dcm_CopyTxData:从 Dcm Tx Buffer 获取待发数据Dcm_TpTxConfirmation:通知最终发送成功或失败
发送确认是请求生命周期的最后阶段。部分服务的后处理动作,例如复位、模式切换或资源释放,必须以 Tx Confirmation 为边界,不能把“调用 PduR 成功”等同于“响应已经在线发送完成”。
横向模块依赖
- EcuM:启动期间调用
Dcm_Init - OS/SchM:周期调度
Dcm_MainFunction - PduR/TP:诊断 N-SDU 接收和响应发送
- ComM:诊断激活时保持网络通信
- Dem:DTC 读取、清除和 DTC Setting
- NvM:按配置保存 Dcm 相关持久数据;DID 业务数据通常由对应应用或服务回调负责其持久化
- BswM:执行
0x28通信控制 - RTE/SWC:DID、Routine、模式切换和应用逻辑
- Det:报告未初始化、空指针、参数和缓冲区越界等开发错误
- Csm/KeyM:支持
0x29认证服务
Dcm 与 Dem 的职责交互
Dcm 负责 UDS 服务层的会话/安全访问检查、请求参数校验和响应编码;Dem 管理 DTC、状态位及诊断记录。以 0x19 ReadDTCInformation 和 0x14 ClearDiagnosticInformation 为例,Dcm 处理协议与访问条件,再通过 Dem 接口读取或清除诊断信息。
sequenceDiagram participant Tester as 诊断仪 participant TP as TP/PduR participant Dcm participant Dem Tester->>TP: UDS 0x19 或 0x14 请求 TP->>Dcm: 完整诊断 N-SDU Dcm->>Dcm: 校验 SID、长度、寻址、Session/Security alt 0x19 ReadDTCInformation Dcm->>Dem: 按子功能查询 DTC/状态/记录 Dem-->>Dcm: 返回配置范围内的诊断信息 Dcm->>Dcm: 编码 0x59 响应 else 0x14 ClearDiagnosticInformation Dcm->>Dem: 请求清除指定 DTC 范围 Dem-->>Dcm: 返回操作结果 Dcm->>Dcm: 编码肯定或否定响应 end Dcm->>TP: 经 PduR 提交响应 TP-->>Tester: UDS 响应
Dem 返回的查询结果受 DTC 配置、状态掩码、故障内存和记录可用性影响;清除请求也不意味着任意非易失存储写入都已在同一时刻物理完成。
典型流程
初始化及 NvM 数据恢复
Dcm 的基础初始化通过 Dcm_Init 完成,通常由 EcuM 在 ECU 启动过程中调用;周期功能则依赖 OS Task 调用 Dcm_MainFunction。如果 Dcm 配置了需要从 NvM 恢复的数据,例如安全失败计数、复位后响应信息或持久化 ROE 状态,Dcm 会在后续周期中读取对应 NvM Block。
sequenceDiagram participant EcuM participant Dcm participant OS participant NvM participant MemIf participant EaFee as Ea/Fee EcuM->>Dcm: Dcm_Init(NULL_PTR) Dcm->>Dcm: 初始化DSL/DSD/DSP上下文 Dcm->>Dcm: 设置Buffer、协议和会话初始状态 Dcm-->>EcuM: return loop 周期任务 OS->>Dcm: Dcm_MainFunction() alt 存在需要恢复的Dcm NvM数据 Dcm->>NvM: NvM_ReadBlock(BlockId, RamBuffer) NvM->>MemIf: Read MemIf->>EaFee: Ea/Fee Read EaFee-->>MemIf: 请求已接受 MemIf-->>NvM: E_OK NvM-->>Dcm: 请求已受理 Note over NvM,EaFee: 物理读取在后续周期异步推进 Dcm->>NvM: NvM_GetErrorStatus(BlockId) alt NVM_REQ_PENDING NvM-->>Dcm: PENDING else NVM_REQ_OK NvM-->>Dcm: OK Dcm->>Dcm: 恢复安全计数/ROE/复位信息 Dcm->>Dcm: 进入可服务状态 else 读取失败 NvM-->>Dcm: Error Dcm->>Dcm: 按配置采用默认值、限制相关功能或上报错误 end else 无持久化数据 Dcm->>Dcm: 直接进入Idle end end
同步 DID 读取
sequenceDiagram participant Tester participant CanTp participant PduR participant DSL as Dcm DSL participant DSD as Dcm DSD participant DSP as Dcm DSP participant SWC participant OS Tester->>CanTp: UDS 0x22 + DID CanTp->>PduR: TP 接收诊断 N-SDU PduR->>DSL: Dcm_StartOfReception(RxPduId, TotalLength) DSL-->>PduR: BUFREQ_OK + BufferSize PduR->>DSL: Dcm_CopyRxData(Data) DSL-->>PduR: BUFREQ_OK PduR->>DSL: Dcm_TpRxIndication(OK) OS->>DSL: Dcm_MainFunction() DSL->>DSD: 分发完整请求 DSD->>DSD: 检查 SID/寻址/Session/Security/长度 DSD->>DSP: Process 0x22 DSP->>DSP: 查找 DcmDspDid DSP->>DSP: 检查 DID 读权限 opt 配置ConditionCheckRead DSP->>SWC: Xxx_ConditionCheckRead() SWC-->>DSP: E_OK end DSP->>SWC: Xxx_ReadData(DataBuffer) SWC-->>DSP: E_OK + DID Data DSP-->>DSD: Positive Response Data DSD->>DSL: 62 + DID + Data DSL->>PduR: PduR_DcmTransmit(TxPduId) PduR->>CanTp: 发送 N-SDU CanTp->>DSL: Dcm_CopyTxData() DSL-->>CanTp: Response Segment CanTp->>Tester: UDS Positive Response CanTp->>PduR: Tx Confirmation PduR->>DSL: Dcm_TpTxConfirmation(OK) DSL->>DSL: 释放请求上下文和 Buffer
Dcm_CopyRxData只做数据搬运,不执行 0x22- DSD 处理通用权限,DSP 处理 DID 特有权限与数据访问
ConditionCheckRead与ReadData是两个不同阶段- 适用的肯定响应 SID 通常为请求 SID 加
0x40 - 请求真正结束于
Dcm_TpTxConfirmation
SecurityAccess 失败
安全访问通常按安全等级维护失败尝试计数。密钥比较失败的计数规则、锁定条件和持久化方式由 Dcm 配置及安全回调实现决定;达到 DcmDspSecurityNumAttDelay 所配置的门限后,可进入由 DcmDspSecurityDelayTime 配置的延时期。配置 DcmDspSecurityBlockIdRef 时,相关失败计数可持久化到 NvM。
sequenceDiagram participant Tester participant Dcm participant SecApp as GetSeed/CompareKey participant NvM participant OS Tester->>Dcm: 27 requestSeed Dcm->>Dcm: 检查延时锁定状态 alt 尚在锁定期 Dcm-->>Tester: 7F 27 37 else 允许尝试 Dcm->>SecApp: GetSeed(DCM_INITIAL) SecApp-->>Dcm: E_OK + Seed Dcm-->>Tester: 67 + Seed Tester->>Dcm: 27 sendKey + Key Dcm->>SecApp: CompareKey(Key, DCM_INITIAL) alt Key正确 SecApp-->>Dcm: E_OK Dcm->>Dcm: 激活SecurityLevel Dcm-->>Tester: Positive Response else Key错误 SecApp-->>Dcm: COMPARE_KEY_FAILED Dcm->>Dcm: AttemptCounter++ opt 配置计数持久化 Dcm->>NvM: 写入安全失败计数 loop NvM写入Pending OS->>Dcm: Dcm_MainFunction() Dcm->>NvM: 查询写入结果 NvM-->>Dcm: PENDING end NvM-->>Dcm: NVM_REQ_OK end alt 达到最大失败次数 Dcm->>Dcm: 启动DelayTime Dcm-->>Tester: 7F 27 36 else 未达到上限 Dcm-->>Tester: 7F 27 35 end end end