Autosar Dem学习笔记-DTC状态位详解与用法

文章目录

  • [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 调试技巧

  1. Dem_GetDTCStatus(或内部 Dem_EvtGetIsoByte)打印 8 bit 十六进制。
  2. 关注 DemTriggerOnDTCStatusChanged / DemTriggerOnEventStatusChanged callback。
  3. Clear 行为差异:
    • Clear DTC 默认会全清(包括 SLC 位)
    • ONLY_THIS_CYCLE_AND_READINESS 只清 TOC 类位(项目有定制 hook)。
  4. 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. 总结与最佳实践

  1. TF 只是起点 ,真正驱动售后和功能的是 CDTC + WIR
  2. PDTC 是"预警",不要让它长期停留在 pending 而不确认或清除。
  3. TNCTOC / TNCSLC 是"测试执行证明",对 OBD 和功能安全监控至关重要。
  4. 善用项目 CustomStatusByte hook 做差异化定制,但不要破坏标准位语义。
  5. 操作循环管理必须与实车驾驶循环对齐,否则 healing 和 TOC 语义全部失效。
  6. UDS 0x19 读取时始终考虑 AvailabilityMask 和客户端 mask 的按位匹配规则。

掌握这 8 个 bit 的每一次置位/清零时机,是做好车载诊断系统的基石。


参考资料

  • AUTOSAR_SWS_DiagnosticEventManager (最新版)
  • ISO 14229-1:2020 Unified Diagnostic Services
  • 本项目 Dem_CustomStatusByte.hDem_EventStatus.cDem_DTCStatusByte.cDem_ISO14229Byte.h

相关推荐
fanchenxinok4 天前
基于图莫斯的CAN UDS诊断上位机-LabVIEW版本(十七):TOOMOSS_SID19_ReadDTCInformation.vi — 读取DTC信息
labview·dtc·sid19
叶修_A14 天前
FS-17 功能安全ISO26262之敏捷开发融合深度解析
敏捷开发·autosar·汽车电子·功能安全·iso26262
YouGIS顽石工坊14 天前
Python GDAL实战:ASTER GDEM V003全国DEM高程数据处理(1123幅分幅合并→34省裁切,30m精度)
gis·遥感·dem·数据处理·空间数据库·数字高程模型·aster gdem
叶修_A1 个月前
FS-11 功能安全ISO26262之生产运维与报废阶段安全保障深度解析
autosar·汽车电子·功能安全·iso26262
原野风霜3241 个月前
认识UDS故障诊断中DTC的形成过程
故障诊断·uds·dtc
齊家治國平天下1 个月前
Google AAOS 中 SOME/IP 框架深度解析:从架构到实践
android·autosar·aaos·车载以太网·some/ip·sdv·vsomeip
叶修_A2 个月前
AP-03 SOME/IP协议实战 - AUTOSAR自适应平台通信中间件深度解析
autosar·汽车电子·some/ip·ap·通信中间件
赞哥哥s2 个月前
Autosar网络管理笔记-被动唤醒和主动请求时Nm报文发送的差异
autosar·网络管理·nm
硅农深芯2 个月前
解读AUTOSAR:定义现代汽车电子的标准化架构
架构·汽车·autosar