4. 诊断描述文件解析

在MICROSAR诊断栈的集成工程中,诊断描述文件是连接“整车诊断需求”与“ECU可执行代码”的桥梁。诊断规范以文档形式定义了服务、数据、寻址和会话行为,而ECU软件需要的是可编译的配置常量、回调函数和状态机参数。描述文件解析环节的核心任务,就是把CDD、ODX、PDX这类结构化描述,转换成Dcm、Dem、CanTp等模块能够直接消费的配置代码。理解这些文件的组织方式、映射规则以及生成器的输入输出边界,是诊断集成能否顺利推进的关键。

一、三类描述文件的定位与结构差异

CDD(CANdela Diagnostic Description)是Vector工具链中常用的诊断描述格式,通常以.cdd文件存在,内部采用类似数据库的层次结构:顶层是ECU,向下依次是诊断服务、子功能、数据标识符(DID)、参数、编码方式和会话/安全状态。CDD的优势在于与CANdelaStudio、DaVinci Configurator等工具链紧密耦合,适合在开发阶段快速迭代诊断数据库。

ODX(Open Diagnostic Data Exchange)是ISO 22901系列定义的开放格式,以.odx文件呈现,采用UML风格的XML结构。ODX把诊断数据分为DIAG-LAYER、ECU-VARIANT、BASE-VARIANT、PROTOCOL等层级,强调可复用和可交换。PDX(Packaged ODX)则是ODX的打包形式,本质是一个ZIP容器,内部包含一个或多个ODX文件以及索引文件index.xml,用于把整车级诊断描述按项目、变体或功能域组织在一起。

三者的关系可以这样理解:PDX是交付容器,ODX是容器内的标准描述单元,CDD是工具链中更贴近配置生成的工程视图。实际项目中,OEM常以PDX形式发布诊断规范,Tier1再将其导入Vector工具链,或直接使用CDD进行配置。

诊断描述文件解析与配置代码生成链路 PDX 包 index.xml ECU_Variant.odx Protocol.odx Function.odx ODX 层级 DIAG-LAYER BASE-VARIANT ECU-VARIANT PROTOCOL CDD 工程视图 ECU 节点 诊断服务 DID / 参数 会话 / 安全状态 诊断服务与数据标识符映射关系 0x22 ReadDataById 0x2E WriteDataById DID 0xF190 DID 0xF187 参数:VIN 参数:PartNo 编码:ASCII 长度:17字节 配置代码生成器 DaVinci Configurator / 自定义脚本 Dcm_Cfg.c / .h Dem_Cfg.c / .h CanTp_Cfg.c / .h 回调函数桩

二、诊断服务与DID的映射逻辑

诊断服务与数据标识符的映射,是描述文件解析中最容易出错、也最需要工程经验的部分。以UDS服务0x22(ReadDataByIdentifier)为例,请求报文格式为22 DID_H DID_L,正响应为62 DID_H DID_L Data...。描述文件中需要明确:该服务支持哪些DID、每个DID对应什么数据、数据长度和编码方式是什么、是否受会话或安全等级限制。

在CDD中,这种映射通常表现为“服务—子功能—DID—参数”的树形结构。例如DID 0xF190映射到VIN码,参数长度为17字节,编码为ASCII,仅在默认会话和扩展会话下可读。在ODX中,同样的信息被拆分为DIAG-COMM(诊断通信)、REQUEST、POS-RESPONSE、DOP(数据对象属性)等元素,通过引用关系组合。解析器需要沿着这些引用链,把分散的XML节点还原成完整的服务—DID—参数映射。

实际工程中,一个常见的映射问题是DID长度与Dcm配置不一致。例如描述文件定义DID 0xF187为10字节的零件号,但Dcm_Cfg中配置的DcmDspDataSize为8,运行时就会触发长度校验失败,返回NRC 0x13(IncorrectMessageLengthOrInvalidFormat)。因此,解析阶段必须把DID长度、编码类型、字节序等属性完整提取,并在生成配置时做一致性检查。

三、配置代码生成器的输入与输出

配置代码生成器的输入通常包括三类:诊断描述文件(CDD/ODX/PDX)、项目级配置参数(如CAN ID、寻址方式、会话超时时间)、以及工具链的模板和规则文件。输出则是Dcm、Dem、CanTp等模块的C代码和头文件,以及回调函数的空实现桩。

以Dcm为例,生成器会输出Dcm_Cfg.c中的服务表、DID表、会话表和安全等级表。服务表记录每个服务的SID、支持的子功能、寻址类型和会话权限;DID表记录DID编号、数据长度、读写权限、编码类型和对应的回调函数指针。Dem部分则生成事件表、DTC表、快照数据和扩展数据记录。CanTp部分生成通道配置、寻址格式和超时参数。

下面是一个简化的Dcm配置片段示例,用于说明生成器输出的结构:

/* Dcm_Cfg.c 片段:DID 0xF190 配置 */
static const Dcm_DspDidType Dcm_DspDid_0xF190 = {
    .Did = 0xF190,
    .DidSize = 17,
    .ReadDataLength = 17,
    .WriteDataLength = 0,
    .DataCoding = DCM_DSP_DATA_CODING_ASCII,
    .ReadPermission = DCM_READ_PERMISSION_DEFAULT,
    .WritePermission = DCM_WRITE_PERMISSION_DISABLED,
    .ReadDataFnc = &Dcm_ReadData_VIN,
    .WriteDataFnc = NULL_PTR
};

这段配置直接对应描述文件中的DID定义。生成器的工作就是把CDD/ODX中的属性翻译成这样的C结构体初始化。如果描述文件中DID 0xF190的权限是“默认会话可读、扩展会话可读、安全等级1可写”,生成器就需要把权限映射为Dcm的会话掩码和安全等级掩码。

四、解析过程中的关键检查点

描述文件解析不是简单的格式转换,而是一次语义校验。工程中建议重点关注以下检查点:

  • DID唯一性:同一ECU下不允许出现重复DID,否则生成器可能覆盖配置或产生编译冲突。
  • 服务与DID的引用完整性:ODX中通过引用ID关联服务与DOP,若引用缺失或指向错误,解析会失败或生成错误映射。
  • 长度与编码一致性:DID长度、参数长度、编码类型三者必须匹配,否则运行时会出现NRC 0x13或数据截断。
  • 会话与安全等级覆盖:每个服务的权限集合必须覆盖所有可能触发该服务的会话状态,避免出现“服务存在但永远不可达”的配置。
  • PDX包完整性:PDX作为ZIP容器,需检查index.xml中列出的ODX文件是否全部存在,避免因打包遗漏导致解析中断。
在实际项目中,建议在生成配置代码之前,先用Vector的ODX检查工具或自定义脚本做一次描述文件静态校验,把DID冲突、引用断裂、长度不匹配等问题提前暴露,而不是等到编译或台架测试阶段才发现。

五、从描述文件到可执行配置的完整闭环

一个完整的解析与生成流程可以概括为:导入PDX/CDD → 解析层级结构 → 提取服务、DID、参数、权限 → 映射到Dcm/Dem/CanTp配置模型 → 生成C代码和回调桩 → 编译集成 → 台架验证。其中,解析阶段输出的中间模型(通常以工具内部数据库或XML形式存在)是后续所有配置的基础。如果中间模型有误,生成代码再规范也无法弥补。

验证环节需要关注:生成的DID表是否与描述文件一致、服务权限是否与规范匹配、回调函数桩是否覆盖所有需要用户实现的数据读写。例如,对于DID 0xF190,生成器会输出Dcm_ReadData_VIN的函数声明,但函数体需要集成工程师根据实际数据源(如NvM、常量表或传感器接口)来实现。如果遗漏了某个回调,链接阶段会报未定义符号,或者运行时返回NRC 0x22(ConditionsNotCorrect)。

因此,描述文件解析的最终交付物不仅是配置代码,还包括一份“待实现回调清单”和“配置一致性检查报告”。前者指导集成工程师完成剩余的手工代码,后者用于在集成前确认描述文件与生成配置之间没有语义偏差。把这两个交付物纳入工程流程,可以显著减少诊断功能在台架和整车阶段的返工。