Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

第四章 Arctic Core源码解析 —— 生产级DCM全拆解

4.1 DCM全景——AUTOSAR诊断栈的透明大厦

你读完标准后,最大的疑问是什么

ISO 14229-1:2013告诉你“0x10是什么、0x27怎么交互、0x36的blockSequenceCounter怎么递增“——但它从来没有告诉你:这些东西在真实ECU代码里长什么样

这一章我们拆开Arctic Core——一个开源的AUTOSAR Classic Platform实现——的诊断栈。Arctic Core的DCM(Diagnostic Communication Manager)源码在diagnostic/Dcm/目录下,五个核心文件,总共一万多行C代码。这一节先让你看清楚这栋“透明大厦“的结构——每一层、每一间房、每一条走廊的命名和职责。


AUTOSAR诊断栈的四模块架构

┌─────────────────────────────────────────────────────────┐
│                  APPLICATION LAYER                       │
│              (SW-Cs, 通过RTE通信)                        │
├─────────────────────────────────────────────────────────┤
│                  诊断服务层                              │
│  ┌──────────┐  ┌────────┐  ┌────┐  ┌──────┐            │
│  │   DCM    │  │  DEM   │  │ Dlt│  │ FiM  │            │
│  │Diagnostic│  │Diagnost│  │    │  │Func  │            │
│  │Comm      │  │Event   │  │Log │  │Inhib │            │
│  │Manager   │  │Manager │  │&Trc│  │Mgmt  │            │
│  └────┬─────┘  └───┬────┘  └──┬─┘  └──┬───┘            │
│       │             │          │        │               │
│       │  DTC状态    │       寄存器/端口/日志接口          │
│       └─────────────┘                                   │
├─────────────────────────────────────────────────────────┤
│            通信层 (PduR)                                 │
│   CanTp / DoIP / FrTp                                   │
├─────────────────────────────────────────────────────────┤
│           硬件抽象层 + 芯片驱动                          │
└─────────────────────────────────────────────────────────┘

这四大模块各自负责诊断管线的不同阶段:

模块完整名称一句话职责
DCMDiagnostic Communication Manager收到UDS请求→解析→分发→执行→回复。诊断通信的核心服务器
DEMDiagnostic Event Manager存储DTC、管理DTC状态位、Debounce、快照/扩展数据
DLTDiagnostic Log and Trace诊断日志记录——将诊断交互写入持久存储或串口输出
FiMFunction Inhibition Manager函数级抑制——根据DTC严重度临时停用ECU的某些功能块

这一章专注DCM——因为它是UDS应用层的全部实现。DEM会在4.8节简要覆盖其与DCM的交互接口。


DCM内部的三层——ISO 14229-1的直接映射

DCM内部进一步分解为三个子模块——对应ISO标准中“诊断请求受理→路由→服务处理“的三个阶段:

       CAN/DoIP → PduR → DCM
                           │
                    ┌──────┴──────────┐
                    │  SID提取/子功能解析
                    │
            ┌───────┤     DSL        │←──────┤ 会话层
            │       │ Diagnostic      │       │
            │       │ Session Layer   │       │
            │       └────────┬────────┘       │
            │                │                 │
            │       ┌────────┴────────┐       │
            │       │      DSD       │←──────┤ 调度层
            │       │ Diagnostic      │       │
            │       │ Service         │       │
            │       │ Dispatcher      │       │
            │       └────────┬────────┘       │
            │                │                 │
            │       ┌────────┴────────┐       │
            │       │      DSP       │←──────┤ 执行层
            │       │ Diagnostic      │       │
            │       │ Service         │       │
            │       │ Processor       │       │
            │       └─────────────────┘       │
            └─────────────────────────────────┘
缩写文件代码量核心职责医院类比
会话层DSLDcm_Dsl.c1828行缓冲区管理、Rx/Tx状态机、S3超时、协议抢占门诊前台——挂号、分配候诊室、到期踢人
调度层DSDDcm_Dsd.c915行SID表查找、会话/安全鉴权、子功能分发、正/负响应创建分诊护士——根据病人的“主诉“判断挂哪个科的号,检查有没有权限
执行层DSPDcm_Dsp.c6492行全部22个UDS服务的业务逻辑实现每个科室的医生——真正执行诊断操作

Dcm.c(358行)是总控——Dcm_InitDcm_MainFunction调用这三个子模块的入口,保证执行顺序是DspPreDsdMain → DsdMain → DspMain → DspTimerMain → DslMain


DSL(会话层)——不仅仅是收发缓冲区

这是DCM的最外层,直接面对传输层(PduR)。DSL的核心状态是一个缓冲区的六态机

NOT_IN_USE → IN_USE → PROVIDED_TO_PDUR → DSD_PENDING_RESPONSE_SIGNALED
                                        → DCM_TRANSMIT_SIGNALED
                                        → PROVIDED_TO_PDUR (发送中)
                                        → PENDING_BUFFER_RELEASE → NOT_IN_USE

这六种状态分别对应UDS请求从“传输层开始接收“到“DCM处理完成、回传响应、释放缓冲“的全部生命周期。DSL有两个Rx缓冲区和两个Tx缓冲区——一个“外部“(大块数据,给传输层的PDU),一个“内部“(本地小buffer,给响应NRC和responsePending等不需要大缓冲的场景)。

DSL还负责:协议启动/停止(StartProtocol/StopProtocol回调链)、会话切换时调用DspResetDiagnosticActivityOnSessionChange、功能寻址和物理寻址的统一管理。


DSD(调度层)——SID表查找器

DSD的核心数据结构是一个SID查找表——DsdServiceTable[]——每一行绑定一个SID、可选的子功能表、会话和安全的鉴权引用表、以及处理函数的函数指针。Arctic Core支持三种协议同时运行——CAN、FlexRay、DoIP——每种协议有自己的DsdServiceTable实例。

DSD的主函数DsdHandleRequest()流程:

1. 从 Rx buffer 读出 SID (pduRxData->SduDataPtr[0])
2. lookupSid(sid) —— 在 SID 表中线性搜索
3. 找到后调用 DspCheckSessionLevel —— 当前会话是否允许这个SID
4. 再调用 DspCheckSecurityLevel —— 当前安全等级是否允许
5. 如果有子功能码——调用 DsdLookupSubService() 查找子功能配置
6. 最终调用 selectServiceFunction → runInternalService(SID)
   —— 这是一个巨大的 switch(SID) 分发到 DspUds* 函数

DSP(执行层)——所有UDS服务在这里变成C代码

6492行的Dcm_Dsp.c是DCM最大的文件——它实现了第2章每一节讲到的全部22个UDS服务的业务逻辑。你在Dsp.c里看到的每一个DspUdsXxx()函数,都直接对应你在第2章读过的那一个SID。

核心结构:

// DspUdsDiagnosticSessionControl(0x10) —— 会话切换
// DspUdsEcuReset(0x11) —— ECU复位
// DspUdsSecurityAccess(0x27) —— Seed/Key
// DspUdsReadDataByIdentifier(0x22) —— 按DID读
// DspUdsWriteDataByIdentifier(0x2E) —— 按DID写
// DspUdsReadDtcInformation(0x19) —— 读DTC
// DspUdsRoutineControl(0x31) —— 例行控制
// ...
// 总计 22+ 个服务处理函数

本篇小结

  1. Arctic Core的DCM遵循AUTOSAR架构——DSL管理通信会话和缓冲区,DSD进行SID路由和鉴权,DSP执行具体的UDS服务逻辑。
  2. Dcm.c作为总控,Init和MainFunction的调用顺序决定三层子模块的执行周期。
  3. DSL的六态缓冲区管理是实现“CAN帧→DCM内部消息→响应回传“全流程的核心。
  4. DSD的SID查找表+会话/安全鉴权+子功能分发形成UDS请求的路由决策树。
  5. DSP是UDS协议规范到C代码的1:1映射——每一节第二章的内容在DSP中有一个函数。

【下集预告】:总控的MainFunction每个周期都干了些什么?Init初始化了什么?PduR把数据喂给DCM后——Dcm_StartOfReception→Dcm_CopyRxData→Dcm_TpRxIndication这三步是怎么协作的?我们拆开Dcm.c的每一行。