4. UDS诊断服务在AURIX上的实现
在AURIX TC3xx上实现UDS诊断,核心不是把ISO 14229的服务表照抄一遍,而是把每个服务的请求解析、会话与安全前置条件、内部动作、响应组装和副作用管理,落到一个可维护的状态机上。AURIX通常作为诊断目标ECU,通过CAN或CAN FD接收请求,由诊断栈完成传输层组包,再交给UDS服务分发层。本节围绕常用服务在AURIX端的实现方式,说明它们如何共享会话、安全等级和DTC状态,并给出一个可落地的状态机设计。
服务分类与共享状态
这些服务可以按“是否改变ECU状态”分为三类。第一类是会话与通信控制类:0x10(DiagnosticSessionControl)、0x28(CommunicationControl)、0x3E(TesterPresent)、0x85(ControlDTCSetting)。它们改变诊断会话、通信使能或DTC记录开关,是其他服务的前置条件。第二类是数据与例程类:0x22(ReadDataByIdentifier)、0x2E(WriteDataByIdentifier)、0x31(RoutineControl)、0x19(ReadDTCInformation)。它们读写数据、执行例程或读取故障信息,多数要求默认会话以上,部分写操作还要求安全解锁。第三类是安全与复位类:0x27(SecurityAccess)、0x11(ECUReset)、0x14(ClearDiagnosticInformation)。0x27是进入受保护操作的门禁,0x11和0x14会改变ECU运行或故障存储状态。
在AURIX端,这些服务不应各自维护私有标志,而应共享一组诊断状态变量:当前会话(default、programming、extended)、安全等级(locked、level1、level2)、通信控制状态(normal、noRxAndTx)、DTC设置使能(enabled、disabled)、以及待执行的复位类型。共享状态的好处是前置条件判断集中,响应码一致,避免某个服务绕过安全校验。
会话与安全状态机
0x10服务是状态机的驱动源。AURIX端收到0x10 01(默认会话)、0x10 02(编程会话)、0x10 03(扩展会话)时,先检查请求的会话是否允许从当前会话跳转。例如从默认会话可以直接进入扩展会话,但进入编程会话通常要求先处于扩展会话并已通过安全访问。跳转成功后,必须重置S3定时器(通常5秒),并在响应中返回P2和P2*参数,例如P2=50ms、P2*=5000ms,告诉测试仪响应超时和增强超时。若请求会话不支持,返回NRC 0x12(subFunctionNotSupported)或0x7E(subFunctionNotSupportedInActiveSession)。
0x27安全访问是两阶段握手:先请求种子(0x27 01或0x27 03),ECU生成随机种子并记录;再发送密钥(0x27 02或0x27 04),ECU用相同算法校验。AURIX端通常用HSM或软件算法生成种子和校验密钥。若密钥错误,返回NRC 0x35(invalidKey),并递增失败计数;连续失败达到阈值(例如3次)后启动延迟锁定,期间返回NRC 0x37(requiredTimeDelayNotExpired)。安全等级解锁后,0x2E、0x31等受保护服务才允许执行。安全状态在会话切换或ECU复位后应回到locked。
数据读写与例程控制
0x22 ReadDataByIdentifier按DID读取数据。AURIX端应维护一张DID表,每个DID对应数据长度、读取函数和所需安全等级。例如DID 0xF190为VIN,长度17字节,默认会话可读;DID 0xF18C为ECU序列号,扩展会话可读。收到请求后,先查表,若DID不存在返回NRC 0x31(requestOutOfRange),若安全等级不足返回NRC 0x33(securityAccessDenied)。读取函数从NVM或RAM中取值,组装成正响应。
0x2E WriteDataByIdentifier与0x22对称,但必须检查DID是否可写、长度是否匹配、安全等级是否满足。写入前建议先做范围校验,例如某标定DID只允许写入0x0000~0x0FFF,超出则返回NRC 0x31。写入成功后更新NVM,并返回正响应。0x31 RoutineControl用于启动、停止和查询例程,子功能为0x01 start、0x02 stop、0x03 requestResults。AURIX端为每个RID注册例程函数,例如RID 0x0203为“擦除应用区”,start时调用Flash擦除,requestResults返回擦除状态。例程执行可能跨多个诊断周期,因此状态机需要记录例程运行状态,避免重复启动。
故障信息与通信控制
0x19 ReadDTCInformation用于读取DTC。常用子功能包括0x02(reportDTCByStatusMask)、0x04(reportDTCSnapshotRecordByDTCNumber)、0x06(reportDTCExtDataRecordByDTCNumber)。AURIX端DTC存储通常由DEM模块管理,每个DTC有状态字节(testFailed、confirmedDTC、pendingDTC等)。0x19 02请求携带状态掩码,ECU返回所有状态字节与掩码按位与非零的DTC及其状态。0x14 ClearDiagnosticInformation按组清除DTC,收到后调用DEM清除接口,并返回正响应。注意0x14通常要求扩展会话,且清除后DTC状态应复位。
0x28 CommunicationControl控制通信。子功能0x00 enableRxAndTx、0x01 enableRxAndDisableTx、0x02 disableRxAndEnableTx、0x03 disableRxAndTx。AURIX端收到后设置通信控制状态,并影响应用报文的收发。0x85 ControlDTCSetting控制DTC记录,子功能0x01 on、0x02 off。关闭DTC设置后,新的故障不再写入DTC存储,但已有DTC保留。0x3E TesterPresent用于保持会话,收到后重置S3定时器并返回正响应;若子功能为0x80,则抑制正响应。0x11 ECUReset按子功能执行复位,例如0x01 hardReset、0x03 softReset。收到后先返回正响应,再触发看门狗或系统复位,确保响应已发出。
状态机实现要点
在AURIX端,建议用一个诊断主循环按固定周期调用UDS状态机。状态机至少包含IDLE、RECEIVING、PROCESSING、RESPONDING、PENDING五个状态。IDLE等待请求;RECEIVING由传输层组包;PROCESSING执行服务处理函数;RESPONDING发送响应;PENDING用于需要长时间执行的例程,此时返回NRC 0x78(requestCorrectlyReceived-ResponsePending),并在完成后发送最终响应。每个服务处理函数返回统一的结果结构:正响应数据、负响应NRC或pending标志。这样0x31长例程和0x11复位都能纳入同一状态机。
最后,服务响应码要统一。常见NRC包括0x11服务不支持、0x12子功能不支持、0x13长度错误、0x22条件不满足、0x31请求超出范围、0x33安全拒绝、0x35密钥无效、0x37延迟未到、0x78响应挂起。AURIX端应在分发层统一做长度检查和会话检查,把服务特有的校验放在各自处理函数中,保证负响应行为可预测、可测试。