ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

AUTOSAR诊断:从DTC到DEM,解析故障码生命周期与配置实践

AUTOSAR诊断:从DTC到DEM,解析故障码生命周期与配置实践 那天售后反馈过来说客户那台车“发动机故障灯”亮着但不抖动也不跛行诊断仪一读出现一个历史故障码P0171。我盯着那个confirmed bit和failed since last clear bit同时存在的状态发了会儿呆——这个场景我见过太多次了。很多刚接触AUTOSAR诊断的同学会把DTC理解成“一个故障码”但实际上在AUTOSAR的软件架构里DTC只是诊断事件管理Diagnostic Event ManagementDEM对外呈现的一张“名片”它背后的Event监控事件、状态位、去抖策略、老化机制才是你真正需要关心的东西。这篇文章基于我参与过的几款域控制器和动力总成项目的DEM开发经验把DTC从监控到上报再到被清除的完整生命周期拆开讲一遍适合刚接手诊断开发、正准备用DaVinci Configurator配置DEM或者苦于搞不清DTC状态字节的工程师参考。1. 写在故障发生之前DEM到底管的是哪一段“人生”1.1 事件Event与 DTC两套容易被混为一谈的概念我接触过的不少开发者都有一个思维惯性看到诊断需求文档里写“电压过低报U0100”就立刻去找工具里怎么配一个叫“U0100”的DTC。这个出发点没错但AUTOSAR的DEM工作方式并不是“DTC数据库”而是“事件处理器”。一个完整的诊断监控项通常由三样东西组成监控逻辑、Event ID、DTC编号。监控逻辑你写在SWC或者CDD里它负责判断“当前这个物理量是否处于故障状态”判断结果会被调用接口通知给DEM这个接口就是Dem_SetEventStatus而你通知DEM的时候带过去的是一个Event IDDEM再根据内部配置找到与之绑定的DTC。也就是说DEM本身不关心你的故障是怎么被判定出来的它只负责接“结果”然后根据你配置好的状态位迁移逻辑去维护DTC状态字节。Event和DTC的关系是多对一还是一对一完全取决于设计。大部分OEM习惯一对一一个含义明确的DTC只对应一条监控事件查起来省事。但如果你做的是UDS 19服务按状态掩码过滤读取多个Event映射到同一个DTC的情况也能用只是后续老化计数和确认逻辑都会互相牵扯不推荐新手上来就这么干。1.2 DEM 管不到的部分从检测到上报的职责边界还有一层分工经常被忽略DEM负责DTC状态的记录与更新但“DTC用什么格式发给诊断仪”“按哪个子功能响应0x19请求”这些事情归DCMDiagnostic Communication Manager诊断通信管理管。UDS报文进来之后DCM解析、调DEM查询结果、组装响应报文。换句话说DEM是一套状态机加存储机制DCM是它面向诊断仪的门面。如果你做过实际项目就会发现当诊断仪读到一个DTC的时候画面上出现的状态字节其实是DEM通过DCM转发出去的。这也解释了为什么你在配置工具里既能看到Dem模块的参数也会看到Dcm模块里关于19、14服务的服务配置两者必须配合使用。2. 实时监控阶段故障从出现到“转正”的甄别过程2.1 一次非法值从何而来监控器的触发路径先看一个最常规的场景你监控的是电池电压SWC周期性读ADC发现电压掉到了3.0V低于你设定的阈值3.2V。这是不是就要立刻把DTC状态字节写成failed如果真这么干诊断仪上会多出一堆因为电瓶拆装、冷启动瞬间压降产生的“幽灵故障码”。所以DEM的前置——或者说你的监控逻辑里——必须有一套确认机制。最常见的设计是监控结果只在“监控条件满足”的前提下才有效。比如车速高于某值才允许做某个DTC的测试发动机运行时间超过多少秒才开始监控或者某个使能条件为真时才能上报。这个“前提”在AUTOSAR里通常用FIM/FID来管后面第4节细说而在SWC侧也可以写成纯逻辑判断。我的经验是使能条件不要全堆在SWC里尽量把“该不该测”的判断留给FID把“是不是故障”的判断留给监控器这样以后OEM要求调整某个DTC的测试前提时你只需要动配置不用改代码。2.2 去抖Debouncing策略把瞬态故障挡在门外当监控器确认了一次“本次测量失败”后怎么决定它到底是不是一个需要记录的故障呢这就是DEM的去抖逻辑。AUTOSAR DEM的去抖方法在配置里有两类常见思路直接去抖和时间去抖。直接去抖其实就是一个计数器每次事件状态为FAILED时加一每次为PASSED时减一直到计数达到阈值才确认故障。时间去抖则是要求故障状态持续一定时间比如连续2秒内始终处于failed状态才确认。我见过最常用的工程做法是计数器式的快速确认加一次“稳定窗口”。比如电池电压这个监控项Fail阈值设为-2、Pass阈值设为2、计数上下限在配置里写清楚连续两次采集都低于门槛就确认故障。DEM的配置参数里会用Debouncing相关字段表示例如DemEventDebouncing...或者生成后出现在DemEventParameter里。这里需要注意去抖计数和老化计数是两套东西。去抖决定“这个DTC当前是不是active”老化决定“之前确认过的故障可不可以被清除”。很多刚入行的同事会在试车时发现故障码明明已经不报了但还留在confirmed状态里就是因为去抖已经翻回去了但老化计数还没跑完。2.3 事件状态与快照/扩展数据记录的联动确认故障之后DEM还会干一件重要的事记录快照数据Snapshot和扩展数据Extended Data。快照就是某个时刻的环境值比如发生故障那一刻的电压、水温、里程。扩展数据往往是DTC的处理次数、老化计数器之类的内部信息。这两个数据不是自动全部记录的需要你在配置里把Event所关联的Snapshot编号、位数、数据源都定义好。最常见的坑是你配了Snapshot但对应的DID数据标识没在Dcm里映射好或者SWC没把快照值写进端口结果19 02子功能读快照时全是0。我每次集成时都会把快照的读取单独做成一条自测用例保证“故障触发那一刻的数据留存”真能跑通而不是只在配置界面里看上去很完整。3. DTC 状态字节八个位决定诊断仪的显示结果3.1 状态位表每一位都对应一个明确语义UDS诊断规范里每个DTC后跟一个字节的状态掩码这8个bit就是DEM向诊断仪呈现的“最终判决”。它们的定义如下Bit术语含义0testFailed当前测试认为该DTC处于失败状态1testFailedThisOperationCycle本操作周期内测试失败过2pendingDTC待确认故障本次失败但还不够“确认”条件3confirmedDTC已确认故障满足确认条件需要被记录/显示4testNotCompletedSinceLastClear自上次清除以来测试尚未完成过5testFailedSinceLastClear自上次清除以来测试失败过6testNotCompletedThisOperationCycle本操作周期测试未完成7warningIndicatorRequested请求点亮故障指示灯的位部分场景用这个表看起来枯燥但你只要记住一条经验就能理清bit0、bit2、bit3是“时序上的三兄弟”。bit0代表刚刚发生了一次失败bit2是介于“刚失败”和“已确认”之间的状态bit3一旦置位就意味着这个故障在存储里已经“定居”了需要走清除或老化流程才能去掉。3.2 状态翻转流程pendingDTC 与 confirmedDTC 的分工用一段串行逻辑描述DTC的“转正”过程监控器上报FAILED后DEM先把bit0和bit1置1同时bit2pending也会置位如果故障条件持续存在并达到了你配置的确认计数Debouncing到达确认阈值bit3confirmed置1。到此为止诊断仪用19 02按状态掩码过滤时就能看到这个DTC了。反过来当监控器上报PASSEDbit0清零去抖计数逐渐衰减如果这个操作周期内一直没再失败bit1、bit6这些周期相关位也会被清除。但bit3不会立即消失它会一直保留直到完成规定的老化循环。所谓老化Aging通常是这样为一个已确认的DTC配置老化循环次数比如“连续10个驾驶循环测试未失败则清除DTC记录”。每完成一个合格的操作循环老化计数减1减到0时DEM清除该DTC的存储记录。我在实际项目里经常发现一个现象开发阶段大家都盯着bit0和bit3看容易忽略bit5自上次清除以来测试失败过。有些OEM验收时会要求“清除DTC后再复测如果故障再现bit5和bit3要一起亮”这其实是用来确认“清除动作真的生效过”的关键证据。4. 该不该报、何时报FIM 和 FID 说了算4.1 功能抑制FIM解决什么问题DEM的监控逻辑本身很“单纯”你喂给它什么状态它就记录什么状态。但整车环境下同一个物理量在不同的条件下其故障判定要求是完全不同的。比如车速信号在ABS/ESP没有完成初始化之前出现异常可能只是因为软件启动时序再比如发动机在拖车启动工况下转速和油压数值都不是常规意义上的“正常值”如果监控器照常判定故障就会报出一堆假DTC。这时候就需要一个前置的“权限判断”机制FIMFunction Inhibition Management和FIDFunction Identifier。FID本质上是一组全局的许可标志每个FID代表一个具体的功能条件比如“整车动力模式正常”“传感器供电稳定”“诊断仪请求了DTC设置控制关闭”。FIM则拿这些FID的当前值去判断当前能不能让某个监控事件去调Dem_SetEventStatus。4.2 FID 的配置逻辑故障事件也讲“前提条件”举个实际配置例子你要抑制“网络通信故障”这个DTC在车辆下线前的报出那就可以定义一个FID名字叫“允许通信安全监控”只有在PDI模式或下线检测通过后才置TRUE。FIM的配置会把这个FID关联到具体Event上并且在DEM事件使能条件中指明“该事件只有在FID为TRUE时才能被更新”。因为FIM/FID在AUTOSAR的ECUC参数里并没有一套绝对统一的模板很多OEM都会在SWC里实现一套自己的抑制逻辑再通过RTE调用DEM接口。我的建议是不要为了“实现简单”而把抑制逻辑全部硬编码到监控SWC里尽量把每个FID的定义、使用范围、置位时机整理成一张配置表因为量产之后最常发生的诊断改动就是“某个DTC在某个特殊工况下不该报但之前没做抑制条件”。5. 配置和集成的落地细节基于 DaVinci Configurator 的实操笔记5.1 EcucDem 参数的核心项到了具体配置阶段以DaVinci Configurator为例你首先要在BSW模块列表里确认Dem模块被启用并挂到正确的EcucPartition上。打开ECUC参数后至少要关注这几个块DemGeneral、DemDtcTable、DemEventTable、DemOperationCycleStorage。DemDtcTable里是DTC编号与DTC状态位映射的定义比如DemDtcNumber、DemDtcStatusBitMask、DemDtcStatusConfirmedBitPosition等。如果你在配置里把确认位设成bit3那么所有该DTC的状态字节都会按bit3来解析。这里有个很坑的细节不同OEM给的状态字节宏定义可能包含整个字节的掩码你千万别直接用0xFF去更新状态字节不然会把该保留的历史信息全部覆盖掉。正确做法是先用掩码读出再在对应位上做 | 和 操作。5.2 事件 ID 与 RTE 的接线方式SWC侧惯用的集成方式是监控SWC的OutputPort发送一个布尔量或枚举量通过RTE映射到DEM模块的接口也可以直接在代码里调用Dem_SetEventStatus。我个人偏好后一种因为可读性好而且方便在调试的时候打断点。#include Dem.h void Monitor_BatteryVoltage(float voltage) { if (voltage 3.2f) { Dem_SetEventStatus(DemConf_DemEvent_BatteryVoltageBelowThreshold, DEM_EVENT_STATUS_FAILED); } else { Dem_SetEventStatus(DemConf_DemEvent_BatteryVoltageBelowThreshold, DEM_EVENT_STATUS_PASSED); } }如果还要存储快照数据那就用带快照参数的变体接口比如Dem_SetEventStatusWithSnapshotData(DemConf_DemEvent_BatteryVoltageBelowThreshold, DEM_EVENT_STATUS_FAILED, DemConf_DemEvent_BatteryVoltageBelowThreshold_SnapshotId, snapshotData)。快照的数据格式必须在配置里提前指定否则接口会拒绝写入。5.3 集成时的常见坑与验证手法下面这些“坑”我基本每次新项目都能遇到列出来给大家排雷Event ID和DTC编号没对应上导致A事件把B的DTC状态刷新了。这类问题排查起来比较费劲最好在配置生成后就做一次“EventId到DTC映射表”的核对把工具生成的Dem_EventId文件抓出来对照诊断矩阵表过一遍。配置了DTC但NVRAM块没分配好。DEM要把confirmed的DTC和老化计数器存储下来如果NVRAM的Block大小不够或者地址重叠下电后再上电故障码就丢了。忘在周期任务里调用Dem_MainFunction。DEM不是纯事件触发的它的循环处理和老化计数推进依赖主函数周期调用。如果你是手写代码集成很容易漏掉这一条。操作循环类型没定义准确。Operation Cycle是DEM判断“本操作周期”和“老化”的时间基准必须和整车定义的电气循环、驾驶循环对齐。例如你定义了“点火循环”但ECU在动力模式下不断电导致老化计数一直不动故障码永远清不掉。19服务的子功能和状态掩码不匹配。比如DCM侧只实现了19 01没实现19 02但DEM里的快照配置齐全那么诊断仪查快照时就会得到不支持响应。我的自测手法很简单在台架上把实际监控条件制造出来按顺序记录DTC状态字节能从0x00翻转到0x05bit0bit2再到0x09bit0bit3然后用14服务清除确认状态字节恢复初始值。跑通这样一条链路基本可以确定DEM核心逻辑没大问题。6. 诊断仪侧的“一生”19/14/85/28 服务如何配合 DEM6.1 19 服务读 DTC 的子功能怎么选UDS的0x19服务有若干子功能最常用的几个和DEM的关系是这样19 01按状态掩码报告匹配的DTC。客户端可以传一个状态掩码比如只查bit3confirmed那么DEM会返回所有已确认故障。如果你的诊断仪界面显示“当前故障”和“历史故障”大部分后端就是19 01配合不同掩码实现的。19 02按状态掩码报告DTC快照。适合故障发生瞬间的环境数据回放需要DEM已经配置好Snapshot并且数据来源完整。19 04报告已确认的DTC相当于19 01的简化版。19 06报告支持的DTC严格说这更多是DCM的配置但数据来源仍然是DEM里的DTC表。做一个项目时千万要先确认诊断仪究竟用哪个子功能。不少国产诊断仪为了通用性会直接用19 02去翻快照结果你只测了19 01C客户现场报“读不到快照”返工成本很高。6.2 清除与冻结14 服务、85 服务的真实作用0x14服务是清除DTC它的触发逻辑是DCM收到14服务请求后调用DEM的数据清除接口把状态字节清零、清除快照和扩展数据、重置老化计数。注意14服务不是“关闭监控”只是清空已存记录如果故障还存在新一次监控照样会把状态位重新置上。0x85服务DTC设置控制作用正好是“控制记录动作”。它把DEM置于“记录开启”或“记录关闭”的状态。下线检测时经常用85服务把驱动相关的DTC记录关掉防止误报污染诊断结果。我在配置时特别提醒85是作用于“DTC设置”的开关跟0x28通信控制不是一回事别把两个服务的作用搞混。下线测试还有一个常见顺序先发85关记录再做该工况的测试结束后先发85开记录再发14清一下可能产生的新状态保证车辆交付时诊断记录干净。6.3 28 服务与诊断事件上报的联动0x28服务是用来控制通信行为的比如抑制特定报文的发送、禁止接收、允许收发等。很多人困惑“28服务会不会影响DTC监控”我的理解是28服务配置的是网络通信通道不是DEM的记录状态。如果你用28服务把某条CAN报文抑制了而DTC的确认条件恰好依赖这条报文的有效数据那确实会间接影响监控结果但那是因为数据没传到不是DEM被关闭了。所以在做DTC上报联调时我一般会同时打开三处观察DEM事件状态、DCM响应的状态字节、总线上对应的诊断报文ID。如果DTC明明在DEM里是confirmed但诊断仪读不到问题大概率出在DCM的19服务路由或者28服务的通信抑制上而不是DEM模块本身。我在这个项目里最大的感受是诊断开发看上去是在配置工具实际上是在不断地“翻译”——把客户的现象翻译成状态字节把状态字节翻译成配置项再把配置项翻译成代码逻辑。DTC的一生从需求文档里的一个编号开始在DEM的状态机里经历失败、确认、老化、清除。把这套流程想透了之后不管是用DaVinci Configurator还是手写配置你都不会再被“故障码读不出来”这种问题卡太久。
返回列表