文章目录
- [DEM DTC 状态位详解与用法(AUTOSAR Classic 实践)](#DEM DTC 状态位详解与用法(AUTOSAR Classic 实践))
-
- [1. 为什么 DTC 状态位如此重要?](#1. 为什么 DTC 状态位如此重要?)
- [2. DTC 状态字节位布局](#2. DTC 状态字节位布局)
- [3. 各状态位详细含义 + 状态迁移](#3. 各状态位详细含义 + 状态迁移)
-
- [3.1 核心状态迁移图](#3.1 核心状态迁移图)
- [3.2 逐 bit 详细说明](#3.2 逐 bit 详细说明)
- [4. 从事件报告到状态位落地的完整流程](#4. 从事件报告到状态位落地的完整流程)
- [5. Confirmed / Pending / Aging 三大机制对比](#5. Confirmed / Pending / Aging 三大机制对比)
- [6. Operation Cycle 对状态位的影响](#6. Operation Cycle 对状态位的影响)
- [7. UDS 0x19 如何使用状态位(Dcm + Dem 交互)](#7. UDS 0x19 如何使用状态位(Dcm + Dem 交互))
- [8. 项目实践(ETAS + 本项目)](#8. 项目实践(ETAS + 本项目))
-
- [8.1 常见配置影响状态位](#8.1 常见配置影响状态位)
- [8.2 调试技巧](#8.2 调试技巧)
- [9. 常见问题与陷阱](#9. 常见问题与陷阱)
- [10. 总结与最佳实践](#10. 总结与最佳实践)
DEM DTC 状态位详解与用法(AUTOSAR Classic 实践)
参考标准 :ISO 14229-1 (UDS)、AUTOSAR_SWS_DiagnosticEventManager (Dem)、AUTOSAR_SWS_DiagnosticCommunicationManager (Dcm)
适用对象:诊断开发、BSW 集成、功能安全监控、标定测试工程师
1. 为什么 DTC 状态位如此重要?
在 AUTOSAR DEM 中,每个诊断事件(Event)最终都会映射到一个或多个 DTC(Diagnostic Trouble Code)。DTC 的"健康状态"不是一个简单的布尔值,而是由一个 8 位状态字节(DTC Status Byte / UDS Status Byte)完整描述。
这个字节直接决定了:
- 诊断仪能否通过 0x19 服务读到这个 DTC(status mask 过滤)
- 是否点亮 MIL / 报警灯(WIR bit)
- 是否进入故障记忆(Event Memory)并存储 FreezeFrame / ExtendedData
- 是否触发 FiM 功能抑制、SWC 降级策略
- 整车诊断会话中"本次循环 / 历史故障"的区分
如果状态位管理混乱,会导致:
- 偶发故障无法被确认(客户投诉)
- 愈合后 DTC 无法自动清除(售后返修困扰)
- UDS 读取返回的状态与实际车辆状态不一致(审核问题)
2. DTC 状态字节位布局
标准 UDS 状态字节(Dem_UdsStatusByteType / ISO 14229 StatusOfDTC)定义如下:

说明:Bit0(LSB 右侧)为 TF,Bit7(MSB 左侧)为 WIR。蓝色位为"测试完成性"相关位,红色/橙色为失败与指示器相关位。初始值使 TNCTOC 与 TNCSLC 同时置位。
| Bit | 名称 (中文) | 英文缩写 | 位置 | 含义简述 |
|---|---|---|---|---|
| 7 | 警告指示器请求 | WIR | MSB | 是否请求点亮故障灯/指示器 |
| 6 | 本操作循环测试未完成 | TNCTOC | - | 本操作循环内测试尚未完成(或未开始) |
| 5 | 上次清除后测试失败 | TFSLC | - | 自上次清除以来,曾经出现过失败 |
| 4 | 上次清除后测试未完成 | TNCSLC | - | 自上次清除以来,测试尚未完成 |
| 3 | 已确认 DTC | CDTC | - | 满足确认条件,DTC 被正式确认 |
| 2 | 待确认 DTC | PDTC | - | 本操作循环内检测到故障,但尚未达到确认阈值 |
| 1 | 本操作循环测试失败 | TFTOC | - | 本操作周期内测试结果为失败 |
| 0 | 测试失败 | TF | LSB | 当前报告为失败 |
初始值(DEM_ISO14229BYTE_INITVALUE):
c
(DEM_ISO14229_BM_TESTNOTCOMPLETE_TOC | DEM_ISO14229_BM_TESTNOTCOMPLETE_SLC)
即上电或清除后,TNCTOC + TNCSLC 置位,表示"尚未完成测试"。
3. 各状态位详细含义 + 状态迁移
3.1 核心状态迁移图

说明:红色表示进入 Confirmed 后的"持久故障记忆"路径;黄色为 Pending 预警状态;绿色为 Aging 自动愈合恢复路径。实际项目中还受 debounce 算法、EnableCondition、StorageCondition 影响。
下面用 Mermaid 给出更精确的简化状态机(实际 DEM 实现中还有 debounce、storage condition、enable condition 等前置判定):
#mermaid-svg-Z510JUyqocTsPYc6{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Z510JUyqocTsPYc6 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Z510JUyqocTsPYc6 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Z510JUyqocTsPYc6 .error-icon{fill:#552222;}#mermaid-svg-Z510JUyqocTsPYc6 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Z510JUyqocTsPYc6 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Z510JUyqocTsPYc6 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Z510JUyqocTsPYc6 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Z510JUyqocTsPYc6 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Z510JUyqocTsPYc6 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Z510JUyqocTsPYc6 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Z510JUyqocTsPYc6 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Z510JUyqocTsPYc6 .marker.cross{stroke:#333333;}#mermaid-svg-Z510JUyqocTsPYc6 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Z510JUyqocTsPYc6 p{margin:0;}#mermaid-svg-Z510JUyqocTsPYc6 defs #statediagram-barbEnd{fill:#333333;stroke:#333333;}#mermaid-svg-Z510JUyqocTsPYc6 g.stateGroup text{fill:#9370DB;stroke:none;font-size:10px;}#mermaid-svg-Z510JUyqocTsPYc6 g.stateGroup text{fill:#333;stroke:none;font-size:10px;}#mermaid-svg-Z510JUyqocTsPYc6 g.stateGroup .state-title{font-weight:bolder;fill:#131300;}#mermaid-svg-Z510JUyqocTsPYc6 g.stateGroup rect{fill:#ECECFF;stroke:#9370DB;}#mermaid-svg-Z510JUyqocTsPYc6 g.stateGroup line{stroke:#333333;stroke-width:1;}#mermaid-svg-Z510JUyqocTsPYc6 .transition{stroke:#333333;stroke-width:1;fill:none;}#mermaid-svg-Z510JUyqocTsPYc6 .stateGroup .composit{fill:white;border-bottom:1px;}#mermaid-svg-Z510JUyqocTsPYc6 .stateGroup .alt-composit{fill:#e0e0e0;border-bottom:1px;}#mermaid-svg-Z510JUyqocTsPYc6 .state-note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-Z510JUyqocTsPYc6 .state-note text{fill:black;stroke:none;font-size:10px;}#mermaid-svg-Z510JUyqocTsPYc6 .stateLabel .box{stroke:none;stroke-width:0;fill:#ECECFF;opacity:0.5;}#mermaid-svg-Z510JUyqocTsPYc6 .edgeLabel .label rect{fill:#ECECFF;opacity:0.5;}#mermaid-svg-Z510JUyqocTsPYc6 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Z510JUyqocTsPYc6 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Z510JUyqocTsPYc6 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Z510JUyqocTsPYc6 .edgeLabel .label text{fill:#333;}#mermaid-svg-Z510JUyqocTsPYc6 .label div .edgeLabel{color:#333;}#mermaid-svg-Z510JUyqocTsPYc6 .stateLabel text{fill:#131300;font-size:10px;font-weight:bold;}#mermaid-svg-Z510JUyqocTsPYc6 .node circle.state-start{fill:#333333;stroke:#333333;}#mermaid-svg-Z510JUyqocTsPYc6 .node .fork-join{fill:#333333;stroke:#333333;}#mermaid-svg-Z510JUyqocTsPYc6 .node circle.state-end{fill:#9370DB;stroke:white;stroke-width:1.5;}#mermaid-svg-Z510JUyqocTsPYc6 .end-state-inner{fill:white;stroke-width:1.5;}#mermaid-svg-Z510JUyqocTsPYc6 .node rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Z510JUyqocTsPYc6 .node polygon{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Z510JUyqocTsPYc6 #statediagram-barbEnd{fill:#333333;}#mermaid-svg-Z510JUyqocTsPYc6 .statediagram-cluster rect{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Z510JUyqocTsPYc6 .cluster-label,#mermaid-svg-Z510JUyqocTsPYc6 .nodeLabel{color:#131300;}#mermaid-svg-Z510JUyqocTsPYc6 .statediagram-cluster rect.outer{rx:5px;ry:5px;}#mermaid-svg-Z510JUyqocTsPYc6 .statediagram-state .divider{stroke:#9370DB;}#mermaid-svg-Z510JUyqocTsPYc6 .statediagram-state .title-state{rx:5px;ry:5px;}#mermaid-svg-Z510JUyqocTsPYc6 .statediagram-cluster.statediagram-cluster .inner{fill:white;}#mermaid-svg-Z510JUyqocTsPYc6 .statediagram-cluster.statediagram-cluster-alt .inner{fill:#f0f0f0;}#mermaid-svg-Z510JUyqocTsPYc6 .statediagram-cluster .inner{rx:0;ry:0;}#mermaid-svg-Z510JUyqocTsPYc6 .statediagram-state rect.basic{rx:5px;ry:5px;}#mermaid-svg-Z510JUyqocTsPYc6 .statediagram-state rect.divider{stroke-dasharray:10,10;fill:#f0f0f0;}#mermaid-svg-Z510JUyqocTsPYc6 .note-edge{stroke-dasharray:5;}#mermaid-svg-Z510JUyqocTsPYc6 .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-Z510JUyqocTsPYc6 .statediagram-note rect{fill:#fff5ad;stroke:#aaaa33;stroke-width:1px;rx:0;ry:0;}#mermaid-svg-Z510JUyqocTsPYc6 .statediagram-note text{fill:black;}#mermaid-svg-Z510JUyqocTsPYc6 .statediagram-note .nodeLabel{color:black;}#mermaid-svg-Z510JUyqocTsPYc6 .statediagram .edgeLabel{color:red;}#mermaid-svg-Z510JUyqocTsPYc6 #dependencyStart,#mermaid-svg-Z510JUyqocTsPYc6 #dependencyEnd{fill:#333333;stroke:#333333;stroke-width:1;}#mermaid-svg-Z510JUyqocTsPYc6 .statediagramTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Z510JUyqocTsPYc6 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 上电/清除后初始
"Dem_SetEventStatus(FAILED) 且 debounce 合格"
"本周期首次失败 + 未达确认阈值"
"满足 Dem 确认计数器 (通常 1 次或配置阈值)"
"连续多周期 qualified pass (Aging 计数达标)"
"Aging 完成或 Clear"
"本周期 qualified pass + ResetEventStatus"
"Clear 或 新周期开始且 pass"
NoFault
TestFailed
Pending
Confirmed
Healing
CDTC=1, 可存储 EventMemory
可触发 WIR / MIL
PDTC=1, TFTOC=1
通常不触发长期动作
3.2 逐 bit 详细说明
Bit 0 - testFailed (TF)
当前"瞬时"失败标志。Dem_SetEventStatus(FAILED) 经 debounce 后立即反映。
注意:即使 TF=1,也不一定存储 DTC,要看 PDTC/CDTC 和存储条件。
Bit 1 - testFailedThisOperationCycle (TFTOC)
本操作循环内是否出现过失败。新操作循环启动时会被清零 (除非失败在同一周期内再次发生)。
常用于区分"本次循环故障"与"历史故障"。
Bit 2 - pendingDTC (PDTC)
"待确认"。本操作循环内检测到故障,但尚未达到确认阈值。
典型场景:间歇性故障、需要多周期确认的严重故障。
清除条件:新操作循环开始且测试完成且 qualified pass、或 Clear DTC。
Bit 3 - confirmedDTC (CDTC)
最关键的位!一旦置位:
- DTC 会被持久化到 Primary Event Memory
- 可被 0x19 0x0A / 0x02 等子功能报告
- 可驱动 Indicator / MIL
- 进入 healing / aging 流程
Bit 4/6 - testNotCompleted (TNCSLC / TNCTOC) *
这两个位非常容易被误解:
- TNCSLC :自上次 Clear 以来,是否从未完成过测试(包括 pass 或 fail)。一旦测试完成(无论结果),该位清零。
- TNCTOC:本操作循环内测试是否尚未完成。新循环开始时重新置位。
诊断仪常用这两个位判断"监控器是否执行过"。
Bit 5 - testFailedSinceLastClear (TFSLC)
自上次清除以来,曾经 失败过(历史痕迹)。即使当前已经 pass,该位也保持,直到 Clear。
对"历史故障统计"非常有用。
Bit 7 - warningIndicatorRequested (WIR)
是否请求激活警告指示器。
- 由 Dem_SetWIRStatus 或 Indicator 管理模块根据配置的 IndicatorAttribute 自动联动。
- 也可在项目 custom hook 中手动控制。
- 通常只有 CDTC + 特定事件类才会真正点灯。
4. 从事件报告到状态位落地的完整流程

说明:PREFAILED 经 debounce 合格后才真正影响 status byte。自定义 hook 可在第 3~6 步之间插入项目特定逻辑。
核心代码路径(ETAS RTA DEM + 项目集成):
c
// SWC / Monitor 典型调用
Dem_SetEventStatus(EventId, DEM_EVENT_STATUS_PREFAILED);
// 或
Dem_SetEventStatus(EventId, DEM_EVENT_STATUS_FAILED);
// 内部关键处理(简化自 Dem_EventStatus.c + Dem_EvtSt_*)
if (debounce qualified failed) {
Dem_ISO14229ByteSetTestFailed(&status, TRUE);
Dem_ISO14229ByteSetTestFailedTOC(&status, TRUE);
Dem_ISO14229ByteSetTestFailedSLC(&status, TRUE);
Dem_ISO14229ByteSetTestCompleteTOC(&status, TRUE);
Dem_ISO14229ByteSetPendingDTC(&status, TRUE); // 视配置
}
// 达到确认条件后
Dem_EvtSt_CustomConfirmation(...) {
Dem_ISO14229ByteSetConfirmedDTC(&status, TRUE);
}
5. Confirmed / Pending / Aging 三大机制对比

说明:三栏分别对应"短期预警""长期确认""自动恢复"三个阶段。颜色与状态位含义一致(黄=Pending,红=Confirmed,绿=愈合)。
| 维度 | PendingDTC | ConfirmedDTC | Aging (愈合) |
|---|---|---|---|
| 触发条件 | 本周期检测到故障 + 未达阈值 | 满足 Dem 确认计数器 | 连续 N 个操作循环 qualified pass |
| 典型存储 | 可能不进 EventMemory | 必须进 Primary Memory | 从 Memory 移除或标记 healed |
| 对 MIL/WIR 影响 | 一般无 | 通常触发 | 关闭指示器 |
| UDS 可见性 | 0x19 子功能可见 | 强烈可见 | 清除后不可见 |
| 清除方式 | 新周期 pass / Clear | Aging 或 Clear | 自动或 Clear |
6. Operation Cycle 对状态位的影响
新操作循环开始(Dem_SetOperationCycleState(START) 或等效的 Dem 内部处理)是状态位重置的重要时机。
#mermaid-svg-fLEG3WnVrZiaoDKi{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-fLEG3WnVrZiaoDKi .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-fLEG3WnVrZiaoDKi .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-fLEG3WnVrZiaoDKi .error-icon{fill:#552222;}#mermaid-svg-fLEG3WnVrZiaoDKi .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-fLEG3WnVrZiaoDKi .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-fLEG3WnVrZiaoDKi .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-fLEG3WnVrZiaoDKi .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-fLEG3WnVrZiaoDKi .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-fLEG3WnVrZiaoDKi .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-fLEG3WnVrZiaoDKi .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-fLEG3WnVrZiaoDKi .marker{fill:#333333;stroke:#333333;}#mermaid-svg-fLEG3WnVrZiaoDKi .marker.cross{stroke:#333333;}#mermaid-svg-fLEG3WnVrZiaoDKi svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-fLEG3WnVrZiaoDKi p{margin:0;}#mermaid-svg-fLEG3WnVrZiaoDKi .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-fLEG3WnVrZiaoDKi .cluster-label text{fill:#333;}#mermaid-svg-fLEG3WnVrZiaoDKi .cluster-label span{color:#333;}#mermaid-svg-fLEG3WnVrZiaoDKi .cluster-label span p{background-color:transparent;}#mermaid-svg-fLEG3WnVrZiaoDKi .label text,#mermaid-svg-fLEG3WnVrZiaoDKi span{fill:#333;color:#333;}#mermaid-svg-fLEG3WnVrZiaoDKi .node rect,#mermaid-svg-fLEG3WnVrZiaoDKi .node circle,#mermaid-svg-fLEG3WnVrZiaoDKi .node ellipse,#mermaid-svg-fLEG3WnVrZiaoDKi .node polygon,#mermaid-svg-fLEG3WnVrZiaoDKi .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-fLEG3WnVrZiaoDKi .rough-node .label text,#mermaid-svg-fLEG3WnVrZiaoDKi .node .label text,#mermaid-svg-fLEG3WnVrZiaoDKi .image-shape .label,#mermaid-svg-fLEG3WnVrZiaoDKi .icon-shape .label{text-anchor:middle;}#mermaid-svg-fLEG3WnVrZiaoDKi .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-fLEG3WnVrZiaoDKi .rough-node .label,#mermaid-svg-fLEG3WnVrZiaoDKi .node .label,#mermaid-svg-fLEG3WnVrZiaoDKi .image-shape .label,#mermaid-svg-fLEG3WnVrZiaoDKi .icon-shape .label{text-align:center;}#mermaid-svg-fLEG3WnVrZiaoDKi .node.clickable{cursor:pointer;}#mermaid-svg-fLEG3WnVrZiaoDKi .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-fLEG3WnVrZiaoDKi .arrowheadPath{fill:#333333;}#mermaid-svg-fLEG3WnVrZiaoDKi .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-fLEG3WnVrZiaoDKi .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-fLEG3WnVrZiaoDKi .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-fLEG3WnVrZiaoDKi .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-fLEG3WnVrZiaoDKi .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-fLEG3WnVrZiaoDKi .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-fLEG3WnVrZiaoDKi .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-fLEG3WnVrZiaoDKi .cluster text{fill:#333;}#mermaid-svg-fLEG3WnVrZiaoDKi .cluster span{color:#333;}#mermaid-svg-fLEG3WnVrZiaoDKi div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-fLEG3WnVrZiaoDKi .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-fLEG3WnVrZiaoDKi rect.text{fill:none;stroke-width:0;}#mermaid-svg-fLEG3WnVrZiaoDKi .icon-shape,#mermaid-svg-fLEG3WnVrZiaoDKi .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-fLEG3WnVrZiaoDKi .icon-shape p,#mermaid-svg-fLEG3WnVrZiaoDKi .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-fLEG3WnVrZiaoDKi .icon-shape .label rect,#mermaid-svg-fLEG3WnVrZiaoDKi .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-fLEG3WnVrZiaoDKi .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-fLEG3WnVrZiaoDKi .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-fLEG3WnVrZiaoDKi :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Yes
No
新 OperationCycle START
Dem_EvtAdvanceOperationCycle
事件受影响?
保存 old status
调用 Dem_EvtSt_HandleNewOperationCycle
清 TFTOC、TNCTOC
若上一周期 complete 且 pass,则清 PDTC
重置 FDC 阈值、InitMonitoring
触发 status change callback
跳过
对应项目实现(Dem_EventStatus.c 片段):
c
Dem_EvtSt_HandleNewOperationCycle(eventId) {
if (custom enabled) {
if (completeTOC && !failedTOC) {
clear PDTC;
}
clear TFTOC;
clear TNCTOC; // 即置 TNCTOC
}
...
}
实践建议:
- 驾驶循环(Driving Cycle)通常映射到 DemOperationCycle "DC";
- 暖机循环、点火循环可单独配置;
- 确保
Dem_EndOperationCycle/Dem_SetOperationCycleState(END)在下电前被正确调用,否则某些 healing 计数不会累加。
7. UDS 0x19 如何使用状态位(Dcm + Dem 交互)
诊断仪最常用的就是通过 status mask 过滤 DTC 列表。
典型子功能:
- 0x01 reportNumberOfDTCByStatusMask
- 0x02 reportDTCByStatusMask
- 0x0A reportSupportedDTC
- 0x12 reportEmissionsRelatedDTC 等
Dem Dcm Tester Dem Dcm Tester #mermaid-svg-rGNHXJqMjkDe1Azs{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-rGNHXJqMjkDe1Azs .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-rGNHXJqMjkDe1Azs .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-rGNHXJqMjkDe1Azs .error-icon{fill:#552222;}#mermaid-svg-rGNHXJqMjkDe1Azs .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-rGNHXJqMjkDe1Azs .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-rGNHXJqMjkDe1Azs .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-rGNHXJqMjkDe1Azs .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-rGNHXJqMjkDe1Azs .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-rGNHXJqMjkDe1Azs .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-rGNHXJqMjkDe1Azs .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-rGNHXJqMjkDe1Azs .marker{fill:#333333;stroke:#333333;}#mermaid-svg-rGNHXJqMjkDe1Azs .marker.cross{stroke:#333333;}#mermaid-svg-rGNHXJqMjkDe1Azs svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-rGNHXJqMjkDe1Azs p{margin:0;}#mermaid-svg-rGNHXJqMjkDe1Azs .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-rGNHXJqMjkDe1Azs text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-rGNHXJqMjkDe1Azs .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-rGNHXJqMjkDe1Azs .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-rGNHXJqMjkDe1Azs .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-rGNHXJqMjkDe1Azs .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-rGNHXJqMjkDe1Azs #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-rGNHXJqMjkDe1Azs .sequenceNumber{fill:white;}#mermaid-svg-rGNHXJqMjkDe1Azs #sequencenumber{fill:#333;}#mermaid-svg-rGNHXJqMjkDe1Azs #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-rGNHXJqMjkDe1Azs .messageText{fill:#333;stroke:none;}#mermaid-svg-rGNHXJqMjkDe1Azs .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-rGNHXJqMjkDe1Azs .labelText,#mermaid-svg-rGNHXJqMjkDe1Azs .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-rGNHXJqMjkDe1Azs .loopText,#mermaid-svg-rGNHXJqMjkDe1Azs .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-rGNHXJqMjkDe1Azs .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-rGNHXJqMjkDe1Azs .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-rGNHXJqMjkDe1Azs .noteText,#mermaid-svg-rGNHXJqMjkDe1Azs .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-rGNHXJqMjkDe1Azs .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-rGNHXJqMjkDe1Azs .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-rGNHXJqMjkDe1Azs .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-rGNHXJqMjkDe1Azs .actorPopupMenu{position:absolute;}#mermaid-svg-rGNHXJqMjkDe1Azs .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-rGNHXJqMjkDe1Azs .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-rGNHXJqMjkDe1Azs .actor-man circle,#mermaid-svg-rGNHXJqMjkDe1Azs line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-rGNHXJqMjkDe1Azs :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} loop 每个匹配的 DTC 19 02 statusMask=0x2F %% PDTC | CDTC | TF | ... 1 Dem_SelectDTC / Dem_GetNumberOfFilteredDTC 2 过滤符合 mask 的 DTC 数量 3 Positive + Count 4 19 02 statusMask=0x08 %% 只关心 Confirmed 5 Dem_SetDTCFilter(..., DEM_UDS_STATUS_CDTC) 6 DTC + 当前 statusByte (已 & AvailabilityMask) 7 DTC + Status 列表 8
重要规则:
- Dem 返回的 statusByte 会被 AvailabilityMask 掩码(配置在 DemDTCStatusAvailabilityMask)。
- 客户端发送的 mask 是"按位与"匹配:
(dtcStatus & mask) == mask才返回。 - 某些子功能只返回特定 bit 置位的 DTC。
8. 项目实践(ETAS + 本项目)
8.1 常见配置影响状态位
DemRbEventStatusBitStorageTestFailed:是否把 TF bit 持久化到 NvM- Confirmation 阈值:DemEventParameter / DemRbEventClass 下的计数器
- Aging 阈值:决定多少个合格循环后清除 Confirmed
- Storage Condition / Enable Condition:即使 SetEventStatus,也可能不更新状态位
- Operation Cycle 绑定:事件属于哪些 Cycle 决定何时重置 TOC 类 bit
8.2 调试技巧
- 用
Dem_GetDTCStatus(或内部Dem_EvtGetIsoByte)打印 8 bit 十六进制。 - 关注
DemTriggerOnDTCStatusChanged/DemTriggerOnEventStatusChangedcallback。 - Clear 行为差异:
Clear DTC默认会全清(包括 SLC 位)ONLY_THIS_CYCLE_AND_READINESS只清 TOC 类位(项目有定制 hook)。
- Mirror Memory 中的 DTC 状态可能独立存储(视
DEM_CFG_EVMEM_MIRROR_MEMORY_DTC_STATUS_STORED)。
9. 常见问题与陷阱
| 问题现象 | 可能原因 | 建议排查 |
|---|---|---|
| 明明失败了,诊断仪读不到 CDTC | 未达到确认阈值、EnableCondition 关闭、Event 被 suppress | 检查 confirmation counter、Dem_EnableDTCSetting |
| 故障愈合后 CDTC 仍为 1 | Aging 阈值配置过高、操作循环未正确结束 | 验证 Dem_SetOperationCycleState + aging 计数 |
| TNCSLC 一直为 1 | 对应监控器从未执行 | 检查运行条件、FiM 抑制、任务调度 |
| WIR 点灯但无 DTC | 直接通过 Dem_SetWIRStatus 设置,或 Indicator 配置独立 | 审查 IndicatorAttribute |
10. 总结与最佳实践
- TF 只是起点 ,真正驱动售后和功能的是 CDTC + WIR。
- PDTC 是"预警",不要让它长期停留在 pending 而不确认或清除。
- TNCTOC / TNCSLC 是"测试执行证明",对 OBD 和功能安全监控至关重要。
- 善用项目 CustomStatusByte hook 做差异化定制,但不要破坏标准位语义。
- 操作循环管理必须与实车驾驶循环对齐,否则 healing 和 TOC 语义全部失效。
- UDS 0x19 读取时始终考虑 AvailabilityMask 和客户端 mask 的按位匹配规则。
掌握这 8 个 bit 的每一次置位/清零时机,是做好车载诊断系统的基石。
参考资料
- AUTOSAR_SWS_DiagnosticEventManager (最新版)
- ISO 14229-1:2020 Unified Diagnostic Services
- 本项目
Dem_CustomStatusByte.h、Dem_EventStatus.c、Dem_DTCStatusByte.c、Dem_ISO14229Byte.h