3. UDS协议核心服务与Stellar/SPC5实现映射
ISO 14229 定义的 UDS 服务并不是一组孤立的命令,而是一条从“会话与安全”到“读写与刷写”的完整能力链。在 ST Stellar(SR6P 系列,多核 Arm Cortex-R52 + 硬件安全模块 HSM)与 SPC5(Power Architecture e200 内核,如 SPC58)上,这条链路的落地方式差异明显:Stellar 更依赖 AUTOSAR 分层与 HSM 协同,SPC5 则常见于裸机或轻量 OS 下的直接寄存器与 CAN 驱动操作。本节按服务逐项拆解实现要点,并给出可对照的配置方法。
会话、复位与故障码管理:0x10 / 0x11 / 0x14 / 0x19
0x10 DiagnosticSessionControl 是所有后续服务的前置条件。默认会话(0x01)下通常只开放 0x10、0x11、0x22、0x3E、0x14、0x19 等基础服务;进入编程会话(0x02)后才允许 0x27、0x34~0x37。在 Stellar 上,会话状态一般由诊断栈(如基于 AUTOSAR Dcm 的配置)维护,P2/P2* 定时参数在 DcmDspSessionRow 中按会话分别配置,例如默认会话 P2=50ms、P2*=5000ms,编程会话可放宽到 P2=5000ms 以容忍 Flash 擦写。SPC5 裸机实现时,会话状态机需自行维护,典型做法是用一个全局变量记录当前会话,并在 0x10 请求处理中校验子功能是否受支持,不支持时回 0x12(subFunctionNotSupported)。
0x11 ECUReset 的关键在于复位类型与响应时序。Stellar 上硬复位(0x01)会触发整个 SoC 复位,诊断栈需在发送肯定响应后、复位前留出足够时间让 CAN 控制器把最后一帧发完,通常做法是先回 0x51,再延时约 10~50ms 后写复位寄存器。SPC5 上可通过 MC_ME 模块的 MCTL 寄存器触发复位,注意区分“应用复位”与“调试复位”,避免刷写过程中误触发导致 Bootloader 状态丢失。
0x14 ClearDiagnosticInformation 与 0x19 ReadDTCInformation 成对使用。0x14 的请求参数是 3 字节 groupOfDTC,0xFFFFFF 表示清除全部。在 Stellar 上,DTC 通常存储在 NVM(如 EEPROM 仿真区或 HSM 管理的安全存储)中,清除操作需通过 NvM 接口写入,并注意与 Dem 模块的事件状态同步。0x19 的子功能较多,工程中最常用的是 0x02(reportDTCByStatusMask)和 0x0A(reportSupportedDTC)。状态掩码 0x08 表示 confirmedDTC,0x01 表示 testFailed,读取结果需按 ISO 14229-1 的 DTC 状态字节逐位解析。
数据读写与安全访问:0x22 / 0x2E / 0x27 / 0x28
0x22 ReadDataByIdentifier 与 0x2E WriteDataByIdentifier 是标定与参数交互的主力。DID 的分配需与整车诊断规范一致,例如 0xF190 为 VIN,0xF18C 为 ECU 序列号。Stellar 上,DID 的读写通常映射到 Dcm 的 Did 配置,读操作可直接从 RAM 或 NVM 取值,写操作需判断会话与安全等级。SPC5 上若采用手写诊断,建议为每个 DID 建立一张表,包含 DID 值、长度、读回调、写回调、所需安全等级,避免在 switch-case 中散落判断。
0x27 SecurityAccess 是刷写与写操作的门槛。典型流程是:请求种子(子功能 0x01)→ ECU 返回随机数 → 客户端用算法计算密钥 → 发送密钥(子功能 0x02)→ ECU 校验。Stellar 上,种子生成与密钥校验可放在 HSM 中执行,利用其真随机数发生器(TRNG)和受保护的密钥存储,防止算法被逆向。SPC5 上常见做法是用软件 PRNG 加固定算法,但需注意种子不能长期不变,且连续失败次数应有限制(如 3 次后锁定一段时间)。安全等级通常分两级:Level 1 用于写标定,Level 2 用于刷写。
0x28 CommunicationControl 用于在刷写前关闭非诊断报文的发送与接收。子功能 0x00(enableRxAndTx)、0x01(enableRxAndDisableTx)、0x02(disableRxAndEnableTx)、0x03(disableRxAndTx)需按需选择。Stellar 上可通过 Com 模块的 IPDU 组控制实现,SPC5 上则直接操作 CAN 控制器的验收滤波器或发送使能位。注意关闭通信后,0x3E TesterPresent 仍需保持,否则会话超时。
例程、刷写与通信保持:0x31 / 0x34~0x37 / 0x3E / 0x85
0x31 RoutineControl 常用于擦除、校验、自检等动作。子功能 0x01 启动、0x02 停止、0x03 请求结果。刷写场景中,0xFF00 常被定义为“擦除内存”,0xFF01 为“校验内存”。Stellar 上,例程可绑定到 Flash 驱动或 HSM 服务;SPC5 上则直接调用 Flash 控制模块的擦除函数,注意擦除期间不能取指于同一 Flash 块,需将关键代码搬到 RAM 执行。
0x34 RequestDownload、0x35 RequestUpload、0x36 TransferData、0x37 RequestTransferExit 构成刷写数据传输链。0x34 中需协商 maxNumberOfBlockLength,Stellar 上受 CAN FD 与诊断栈缓冲区限制,常见取 0x0FFE 或更小;SPC5 上若用经典 CAN,通常取 0x0FFE 以下。0x36 的 blockSequenceCounter 从 0x01 开始循环,接收方需校验连续性,否则回 0x73(wrongBlockSequenceCounter)。
0x3E TesterPresent 用于保持非默认会话,子功能 0x00 需抑制肯定响应(suppressPosRspMsgIndicationBit=1),否则总线上会出现大量 0x7E 响应。0x85 ControlDTCSetting 用于在刷写期间关闭 DTC 记录,子功能 0x01 开启、0x02 关闭,避免刷写过程中的异常触发误报。
配置方法对照与常见陷阱
在 Stellar 上,Dcm 的配置通常通过 ARXML 或配置工具完成,关键参数包括 DcmDspSessionRow 的 P2ServerMax、P2StarServerMax,以及 DcmDspSecurityRow 的种子长度、密钥长度、失败计数阈值。若使用 HSM 做安全访问,需在 HSM 固件中实现种子生成与密钥校验接口,并通过 IPC 与主核通信。SPC5 上若采用手写诊断,建议把服务处理函数按服务号注册到一张分发表中,每个表项包含服务号、所需会话、所需安全等级、处理函数指针,这样新增服务时只需加表项,不必改动主循环。
常见陷阱有三类。第一,0x27 安全等级与会话不匹配:在默认会话下请求 Level 2 种子,ECU 应回 0x7F 0x27 0x33(securityAccessDenied),而不是直接返回种子。第二,0x36 块序号不连续:若客户端跳号,ECU 应回 0x73,并终止当前传输,等待新的 0x34。第三,0x3E 未抑制响应:在刷写过程中,若 0x3E 每次都回 0x7E,会占用总线带宽并可能干扰 0x36 的数据流,因此必须设置 suppressPosRspMsgIndicationBit。
下面给出一份可直接对照的配置检查表,用于在 Stellar 或 SPC5 上逐项确认服务实现是否完整。
| 服务 | 关键配置项 | Stellar 落点 | SPC5 落点 | 典型错误响应 |
|---|---|---|---|---|
| 0x10 | 会话子功能、P2/P2* | DcmDspSessionRow | 全局会话变量+定时器 | 0x12 / 0x13 |
| 0x27 | 种子长度、算法、失败阈值 | HSM 接口 + DcmSecurity | 软件 PRNG + 计数 | 0x33 / 0x35 / 0x36 |
| 0x22/0x2E | DID 表、读写回调、安全等级 | DcmDid + NvM | DID 分发表 | 0x31 / 0x33 |
| 0x34 | maxNumberOfBlockLength | DcmDspData + CAN FD | Flash 驱动缓冲区 | 0x13 / 0x31 |
| 0x36 | 块序号校验、超时 | Dcm 传输层 | 接收状态机 | 0x73 / 0x71 |
| 0x3E | 抑制响应位 | Dcm 自动处理 | 手动判断 bit7 | — |
把上述服务按“会话→安全→读写→刷写→保持”的顺序串起来,就得到一条完整的诊断与刷写链路。Stellar 的优势在于 HSM 与 AUTOSAR 栈的成熟度,适合功能安全要求高的场景;SPC5 的优势在于实现轻量、可控性强,适合成本敏感或需要深度定制的项目。无论哪条路径,服务号、子功能、响应码和定时参数都必须严格遵循 ISO 14229-1,否则整车诊断仪将无法正确解析。