본문 바로가기
AUTOSAR 심화

AUTOSAR Dem 완벽 이해: 오류 감지와 DTC 관리의 모든 것

by 버그없는토마토 2025. 12. 18.

AUTOSAR Dem 완벽 이해: 오류 감지와 DTC 관리의 모든 것

Dem이란? DTC란?

DEM이란?


들어가며

지난 시간에 NvM이 어떻게 데이터를 안전하게 저장하는지 배웠어요.

이제 "그 데이터가 뭐가 저장되는가?"를 배워야 할 차례예요.

실무를 접하다보면 시스템->기능->진단 순으로 구현을 하게되는데

여기서 까다롭기도하지만 중요한게 바로 DTC예요

DTC는 이슈가 발생했을때나 제어기의 상태를 판단하는데 아주 큰 역할을 하죠!

 

 

방금 전 제가 말씀 드린 것은 실무자, 개발자의 입장이에요

DTC의 역할은 그 뿐 아니고 실제 차가 양산됐을때에 더 큰 역할을 하죠.

 

예시를 한번 들어보죠.

실제 시나리오:

주행 중 O2 센서 고장!
↓
Dem이 감지 → "고장이야!"
↓
DTC 생성 → "O2 센서 저전압"
↓
NvM이 저장 → 플래시에 기록
↓
"Check Engine" 경고등 점등!
↓
정비소 방문
↓
Dcm이 DTC 읽음 → "O2 센서 교체하세요"
↓
센서 교체 → 정비소가 DTC 삭제

 

DTC (Diagnostic Trouble Code) 같은 오류 코드는 누가 만들까요?

답은 Dem (Diagnostic Event Manager)이에요.

 

모든 시작점은 Dem이에요!

 

이번 시간에는 Dem이 정확히 뭔지, DTC는 어떻게 생성되는지,
상태 머신은 뭔지
상세히 설명해보겠습니다.


📋 Dem이란?

Dem의 정의

Dem = Diagnostic Event Manager

자동차 ECU에서 오류(고장)를 감지하고, DTC(오류 코드)를 생성·관리하는 시스템이에요.

Dem의 역할 (3가지)

1️⃣ 오류 감지 (Fault Detection)
   └─ 센서, 통신, 시스템의 고장 감지

2️⃣ DTC 생성 (DTC Generation)
   └─ P0123 같은 오류 코드 자동 생성

3️⃣ 오류 기록 (Fault Logging)
   └─ 오류 이력 저장 (언제, 몇 번, 어떤 값)

Dem vs 다른 모듈

| 모듈 | 역할 | 예시 |
|------|------|------|
| Dem | 오류 감지 & DTC 생성 | "P0123 생성!" |
| NvM | 오류 저장 | "DTC 플래시에 저장" |
| Dcm | 정비소와 통신 | "진단기에 DTC 전송" |

협력 관계:
Dem이 DTC 생성
  ↓
NvM이 저장
  ↓
Dcm이 읽어서 정비소에 전송

🚨 DTC: Diagnostic Trouble Code

DTC란?

DTC = 자동차 고장을 나타내는 5자리 코드

DTC 구조

P0117
├─ P: Powertrain (동력 시스템)
│     P = Powertrain
│     C = Chassis (섀시)
│     B = Body (차체)
│     U = Network (통신)
│
├─ 0: 표준 (SAE)
│     0 = SAE 표준
│     1 = 제조사 확장
│
├─ 1: 영역 (SubFunction)
│     0-3 = 연료/공기 시스템
│     4-7 = 점화/기관 제어
│     8-9 = 배출가스 시스템
│
└─ 17: 오류 종류 (Specific Fault)
      01-99 = 각 오류별 번호

 

DTC의 상태 (3가지)

1️⃣ PENDING (대기 상태)
   - 오류 조건 감지됨
   - 하지만 아직 "확정"되지 않음
   - 1~2회 주행해봐야 확정
   - 용도: 일시적 오류 배제

2️⃣ CONFIRMED (확정 상태)
   - 오류가 여러 번 반복 확인됨
   - "Check Engine" 경고등 점등!
   - NvM에 저장됨
   - 정비소에서 읽을 수 있음

3️⃣ PASSED (통과 상태)
   - 오류 조건이 더 이상 감지되지 않음
   - 센서 교체 후 이 상태가 됨
   - 일정 주행 거리 후 DTC 자동 삭제

🔍 오류 감지 메커니즘

Dem 모니터링 (Monitoring)

Dem은 다양한 방식으로 오류를 감지해요.

1️⃣ 범위 검사 (Range Monitoring)
   ──────────────────────────────
   O2 센서 전압이 정상 범위인가?

   정상: 0.4V ~ 0.6V

   읽은 값: 0.0V (너무 낮음!)
   → "P0117: O2 센서 저전압" DTC 생성!

   읽은 값: 5.0V (너무 높음!)
   → "P0118: O2 센서 고전압" DTC 생성!

2️⃣ 신호 일관성 검사 (Signal Consistency)
   ──────────────────────────────
   엔진 RPM과 차량 속도가 일치하나?

   상황:
   - 엔진 RPM: 3000 (높음)
   - 차량 속도: 0 km/h (정지)
   - → 뭔가 이상함!

   가능한 원인:
   - 속도 센서 고장
   - 변속기 오류

   → DTC 생성!

3️⃣ 통신 감시 (Communication Monitoring)
   ──────────────────────────────
   CAN 버스에서 다른 ECU의 신호를 받나?

   정상: 50ms마다 신호 수신
   오류: 100ms 이상 신호 없음!

   → "U0100: 엔진 ECU와 통신 손실" DTC!

4️⃣ 액추에이터 피드백 검사 (Actuator Feedback)
   ──────────────────────────────
   연료 분사 명령을 내렸을 때 실제로 분사되나?

   명령: "분사해!"
   피드백: "분사 완료!" (정상)

   명령: "분사해!"
   피드백: 없음! (인젝터 고장)

   → DTC 생성!

🔄 Dem 상태 머신

Dem은 4가지 상태를 순환하며 오류를 관리해요.

                    ┌─────────────┐
                    │   PASSED    │ (통과)
                    │ (오류 없음) │
                    └──────┬──────┘
                           │
                   오류 감지!│
                           ▼
              ┌────────────────────────┐
              │  TENTATIVE PENDING     │ (임시 대기)
              │  (1회 감지됨)          │
              └──────┬──────────┬──────┘
                     │          │
        추가 감지 확인│          └─ 오류 사라짐
        (2회 이상)   │                ↓
                     │          ┌─────────────┐
                     │          │  PASSED     │
                     │          │ (통과)      │
                     │          └─────────────┘
                     ▼
         ┌─────────────────────┐
         │  CONFIRMED PENDING  │ (확정 대기)
         │  (여러 번 감지)     │
         └──────┬──────────┬──────┘
                │          │
      가능성 확인│          └─ 오류 사라짐
      되었음!  │                ↓
                │          ┌─────────────┐
                │          │  PASSED     │
                │          │ (통과)      │
                │          └─────────────┘
                ▼
   ┌──────────────────────┐
   │  CONFIRMED FAILED    │ (확정 실패)
   │ (오류 확정!)        │
   │ DTC 저장!           │
   │ "Check Engine" 점등 │
   └──────┬──────────────┘
          │
  오류 사라짐 (센서 교체 등)
          │
          ▼
  ┌──────────────────────┐
  │  TESTED SINCE CLEAR  │ (테스트 후)
  │ (검사 후 통과 중)    │
  │ (일정 거리 주행)     │
  └──────┬──────────────┘
         │
  일정 주행 거리 후
  DTC 자동 삭제
         ▼
  ┌──────────────────────┐
  │  PASSED             │
  │ (완전히 통과!)      │
  └─────────────────────┘

상태 전환 시나리오

[주행 1일차]
O2 센서: 정상 (0.5V) → PASSED

[주행 2일차]
O2 센서: 갑자기 0.0V (저전압!)
→ "1회 감지" → TENTATIVE PENDING

[다음 주행]
O2 센서: 여전히 0.0V
→ "2회 감지 확인" → CONFIRMED PENDING
→ "Check Engine" 경고등 점등!
→ NvM: DTC P0117 저장

[주행 1주일 후]
정비소 방문
→ O2 센서 교체

[교체 후]
O2 센서: 정상 (0.5V)
→ CONFIRMED FAILED → TESTED SINCE CLEAR
(DTC는 아직 있음, 하지만 "현재는 통과" 표시)

[100km 주행 후]
정상이 계속 유지됨
→ PASSED (DTC 자동 삭제!)

📡 Dem API (Application Programming Interface)

주요 API들

1️⃣ Dem_SetEventStatus
   ─────────────────────────
   목적: 모니터링 결과를 Dem에 전달

   선언:
   Std_ReturnType Dem_SetEventStatus(
       Dem_EventIdType EventId,
       Dem_EventStatusType EventStatus
   );

   사용 예:
   // O2 센서 모니터링 SWC에서
   if (o2_voltage < 0.4 || o2_voltage > 0.6) {
       Dem_SetEventStatus(DemEventId_O2SensorLow, 
                         DEM_EVENT_STATUS_FAILED);
   } else {
       Dem_SetEventStatus(DemEventId_O2SensorLow,
                         DEM_EVENT_STATUS_PASSED);
   }

   EventStatus 값:
   - DEM_EVENT_STATUS_PASSED: 정상
   - DEM_EVENT_STATUS_FAILED: 오류
   - DEM_EVENT_STATUS_TENTATIVE: 임시 오류

2️⃣ Dem_GetEventStatus
   ─────────────────────────
   목적: 특정 오류의 현재 상태 조회

   선언:
   Std_ReturnType Dem_GetEventStatus(
       Dem_EventIdType EventId,
       uint8* EventStatusByte
   );

   사용 예:
   uint8 status;
   Dem_GetEventStatus(DemEventId_O2SensorLow, &status);

   if (status == DEM_EVENT_STATUS_FAILED) {
       // "Check Engine" 경고등 점등하기
       SetWarningLamp(CHECK_ENGINE_LAMP);
   }

   반환 상태 (EventStatusByte):
   Bit 0: Test Failed (이번 주기에 실패했나?)
   Bit 1: Test Failed This Operation Cycle
   Bit 2: Test Not Completed This Operation Cycle
   Bit 3: Test Failed Since Last Clear
   Bit 4: Test Not Completed Since Last Clear
   Bit 5: Component Test Failed
   Bit 6: Component Test Failed This Cycle
   Bit 7: Component Test Not Completed

3️⃣ Dem_GetDTCOfEvent
   ─────────────────────────
   목적: 특정 이벤트의 DTC 코드 조회

   사용 예:
   uint32 dtc;
   Dem_GetDTCOfEvent(DemEventId_O2SensorLow, &dtc);
   // dtc = 0x0117 (P0117)

4️⃣ Dem_ClearDTC
   ─────────────────────────
   목적: DTC 삭제 (정비소에서 호출)

   선언:
   Std_ReturnType Dem_ClearDTC(void);

   용도:
   - 정비소에서 센서 교체 후 호출
   - 진단기(Dcm)가 호출

   예:
   // 정비소 진단기에서
   Dcm_Service_ClearDiagnosticInformation();
   → Dem_ClearDTC() 호출
   → NvM_EraseNvBlock(DTC_Block) 호출

5️⃣ Dem_GetNumberOfFilteredDTC
   ─────────────────────────
   목적: 현재 저장된 DTC 개수 조회

   사용 예:
   uint16 dtc_count;
   Dem_GetNumberOfFilteredDTC(&dtc_count);

   if (dtc_count > 0) {
       // DTC가 있음 → "Check Engine" 켜기
   }

🔗 Dem과 다른 모듈의 협력

Dem ↔ NvM (메모리 관리)

정상 상황:
O2 센서: 0.5V (정상)
→ Dem: PASSED
→ NvM: 아무것도 안 함

오류 발생:
O2 센서: 0.0V (저전압)
→ Dem: "P0117 발생!" (CONFIRMED_FAILED)
→ Dem이 내부적으로 Dcm에게 알림
→ NvM_WriteBlock(DTC_Block, p0117_data)
→ "Check Engine" 경고등 점등!

다음 시동:
→ Dem_Init()
→ NvM_ReadBlock(DTC_Block)
→ DTC P0117 복구!
→ 정비소에서 확인 가능

Dem ↔ Dcm (진단 통신)

정비소 진단:

1️⃣ 진단기 연결
   → Dcm이 Dem에 요청
   "현재 DTC 뭐야?"

2️⃣ Dem이 응답
   "P0117이 있어요"

3️⃣ Dcm이 Dem 조회
   Dem_GetEventStatus(DemEventId_O2Sensor)

4️⃣ Dcm이 진단기에 전송
   "P0117: O2 Sensor Low Voltage"

5️⃣ 정비사: "O2 센서 교체하겠습니다"

6️⃣ 센서 교체 후
   진단기: "DTC 삭제해주세요"
   → Dcm_Service_ClearDiagnosticInformation()
   → Dem_ClearDTC()
   → NvM_EraseNvBlock(DTC_Block)
   → DTC 완전 삭제!

⚙️ Dem 설정 (ARXML)

<?xml version="1.0" encoding="UTF-8"?>
<AUTOSAR xmlns="http://autosar.org/schema/r4.0">
  <AR-PACKAGES>
    <AR-PACKAGE>
      <SHORT-NAME>Dem</SHORT-NAME>
      <ELEMENTS>

        <!-- Event 1: O2 센서 저전압 -->
        <DEM-EVENT>
          <SHORT-NAME>DemEventId_O2SensorLow</SHORT-NAME>
          <EVENT-ID>1</EVENT-ID>
          <DTC>
            <DTC-VALUE>0x0117</DTC-VALUE> <!-- P0117 -->
            <SEVERITY-CLASS>ERROR</SEVERITY-CLASS>
            <FUNCTIONAL-UNIT>POWER_TRAIN</FUNCTIONAL-UNIT>
          </DTC>
          <EVENT-CONTROLLED-TIMING>
            <DEM_DEBOUNCE>
              <DEBOUNCE-COUNTER>2</DEBOUNCE-COUNTER>
              <!-- 2회 연속 감지되어야 CONFIRMED -->
            </DEM_DEBOUNCE>
          </EVENT-CONTROLLED-TIMING>
          <STORAGE-CONDITIONS>
            <STORAGE-ENABLED>true</STORAGE-ENABLED>
            <!-- NvM에 저장 -->
          </STORAGE-CONDITIONS>
        </DEM-EVENT>

        <!-- Event 2: 엔진 온도 센서 고전압 -->
        <DEM-EVENT>
          <SHORT-NAME>DemEventId_CoolantTempHigh</SHORT-NAME>
          <EVENT-ID>2</EVENT-ID>
          <DTC>
            <DTC-VALUE>0x0118</DTC-VALUE> <!-- P0118 -->
            <SEVERITY-CLASS>ERROR</SEVERITY-CLASS>
          </DTC>
          <EVENT-CONTROLLED-TIMING>
            <DEM_DEBOUNCE>
              <DEBOUNCE-COUNTER>3</DEBOUNCE-COUNTER>
            </DEM_DEBOUNCE>
          </EVENT-CONTROLLED-TIMING>
        </DEM-EVENT>

      </ELEMENTS>
    </AR-PACKAGE>
  </AR-PACKAGES>
</AUTOSAR>

설정 항목 설명:

EVENT-ID: 이벤트 고유 번호
DTC-VALUE: DTC 코드 (P0117 = 0x0117)
SEVERITY-CLASS: 중요도 (ERROR, WARNING)
DEBOUNCE-COUNTER: 오류 확정에 필요한 연속 감지 횟수
STORAGE-CONDITIONS: NvM에 저장할 것인가?

📊 실제 Dem 작동 시나리오

시나리오 1: 센서 고장 감지 (실시간)

Time: 0ms (정상 주행)
O2 센서: 0.5V (정상)
→ O2Sensor_Monitoring_10ms() 실행
→ Dem_SetEventStatus(DemEventId_O2SensorLow, 
                     DEM_EVENT_STATUS_PASSED)

Time: 50ms (여전히 정상)
O2 센서: 0.5V
→ PASSED (계속)

Time: 100ms (고장!)
O2 센서: 0.0V (저전압!)
→ O2Sensor_Monitoring_10ms() 실행
→ if (voltage < 0.4) {
     Dem_SetEventStatus(DemEventId_O2SensorLow,
                        DEM_EVENT_STATUS_FAILED);
   }

Time: 110ms
Dem 상태: TENTATIVE_PENDING (1회 감지)
"아직 확정 아님, 계속 모니터링하자"

Time: 110ms (다음 주행)
O2 센서: 여전히 0.0V
→ Dem_SetEventStatus(..., DEM_EVENT_STATUS_FAILED);

Time: 120ms
Dem 상태: CONFIRMED_PENDING
"2회 연속 감지! 이제 확정!"
→ NvM_WriteBlock(DTC_Block, ...)
→ "Check Engine" 경고등 점등!
→ 사용자 보임!

Time: 200ms
Dem이 Dcm에게 알림
"DTC P0117 발생했어!"

User가 인지:
"Check Engine 경고등이 켜졌어? 
정비소 가야겠다"

Time: 1000ms (정비소)
진단기 연결
Dcm_ReadDTC_Service()
→ Dem_GetDTCOfEvent()
→ P0117 반환
→ 정비기에 표시

정비사: "O2 센서 저전압이네요. 교체하겠습니다."

시나리오 2: DTC 삭제 (정비소)

센서 교체 완료!

Time: 500ms (교체 후 시동)
O2 센서: 0.5V (정상)
→ Dem_SetEventStatus(..., DEM_EVENT_STATUS_PASSED)

Time: 510ms
Dem 상태: TENTATIVE_PASSED
(한 번은 통과했어, 계속 모니터링)

Time: 600ms
여전히 0.5V (정상)
→ Dem_SetEventStatus(..., DEM_EVENT_STATUS_PASSED)

Time: 610ms
Dem 상태: CONFIRMED_FAILED
→ TESTED_SINCE_CLEAR
(오류는 있지만, 현재는 통과 중)

정비사: "이제 DTC를 삭제해주세요"
→ 진단기에서 "Clear DTC" 명령

Dcm_Service_ClearDiagnosticInformation()
→ Dem_ClearDTC()
→ NvM_EraseNvBlock(DTC_Block)
→ "Check Engine" 경고등 꺼짐!

결과:
- NvM: DTC 완전 삭제
- Dem: 상태 초기화 (PASSED로)
- User: 경고등 사라짐! ✓

🎯 면접 예상 질문 10가지

Q1: Dem이 뭐고, 알고 있다면 왜 필요해요?
A: "Dem은 오류를 감지하고 DTC를 생성·관리하는 
   시스템입니다. 센서 고장, 통신 오류 등을 감지해서 
   정비소에서 어디가 고장났는지 알 수 있게 합니다."

Q2: DTC가 뭐예요?
A: "Diagnostic Trouble Code의 약자로, 
   P0117처럼 자동차 고장을 나타내는 5자리 코드입니다. 
   P는 Powertrain, 0은 표준, 1은 영역, 17은 
   구체적 오류를 나타냅니다."

Q3: DTC 상태가 몇 가지나 되나요?
A: "3가지입니다. PENDING (임시), CONFIRMED (확정), 
   PASSED (통과)입니다. 오류는 여러 번 감지되어야 
   CONFIRMED로 확정됩니다."

Q4: Debounce는 뭐죠?
A: "오류가 1회만 감지되면 일시적 오류일 수 있으니까, 
   여러 번 연속 감지되어야 확정하는 메커니즘입니다. 
   일반적으로 2~3회 연속 감지되어야 CONFIRMED가 됩니다."

Q5: Dem_SetEventStatus는 뭐하는 건가요?
A: "모니터링 SWC가 센서를 검사한 결과를 Dem에 전달하는 
   함수입니다. PASSED나 FAILED 상태를 보내면 
   Dem이 상태를 관리합니다."

Q6: 왜 DTC가 NvM에 저장되어야 하나요?
A: "시동을 껐다 켜도 오류 이력이 유지되어야 
   정비소에서 진단할 수 있기 때문입니다. 
   휘발성 메모리(RAM)에만 있으면 시동 끄면 사라져요."

Q7: Dem과 NvM은 어떻게 협력하나요?
A: "Dem이 오류를 감지해서 DTC를 생성하면, 
   NvM이 그것을 플래시에 저장합니다. 
   다음 시동 후 Dem_Init()이 NvM에서 
   이전 DTC를 읽어 복구합니다."

Q8: Dem과 Dcm의 차이는?
A: "Dem은 ECU 내부에서 오류를 감지·관리하고, 
   Dcm은 정비소 진단기와 통신합니다. 
   Dem이 만든 DTC를 Dcm이 읽어서 
   진단기에 보내줍니다."

Q9: "Check Engine" 경고등은 누가 켜나요?
A: "Dem이 DTC를 CONFIRMED_FAILED로 확정하면, 
   HMI (사용자 인터페이스) SWC가 경고등을 켭니다. 
   정비소에서 DTC를 삭제해야 꺼집니다."

Q10: DTC를 정비소에서 삭제하면 어떻게 되나요?
A: "Dcm_Service_ClearDiagnosticInformation()이 호출되고, 
   내부적으로 Dem_ClearDTC()가 실행됩니다. 
   Dem이 NvM_EraseNvBlock(DTC_Block)을 호출해서 
   플래시의 DTC를 삭제합니다."

정리: Dem의 핵심

항목 설명
정의 오류 감지 & DTC 생성·관리
DTC P0117처럼 고장을 나타내는 코드
상태 PENDING, CONFIRMED, PASSED
모니터링 범위, 일관성, 통신, 액추에이터
Debounce 오류 확정 전 여러 번 감지 필요
저장 NvM이 DTC를 플래시에 저장
조회 Dcm이 DTC를 읽어서 정비기에 전송
삭제 정비소에서 센서 교체 후 DTC 삭제

마치며

익숙했던 사람도 계실거고, 생소한 사람도 있을거예요

ASW 개발자라면 DEM모듈까지는 생소했을거예요

BSW를 공부한 사람이라면 익숙했겠지만요

 

그래도 DTC는 익숙하죠

시스템개발자도 소프트웨어설계자도 소프트웨어 검증을 담당하는 사람도 모두 DTC는 익숙할거예요

그 DTC가 써지기까지 먼저 감지하는 역할을 한다고 생각하면 쉬워요

DTC의 더 깊숙한 버전? 그정도로 이해해도 됩니다.

 

그런데 이 DTC를 정비소 진단기와 어떻게 주고받을까요?
어떤 프로토콜로? 어떤 명령으로?

 

다음 게시물에서는 "AUTOSAR Dcm 완벽 이해: 진단 통신의 모든 것"을 포스팅해볼게요

DEM과 비슷하게 생겼죠 DCM...?

연관되어 있고, 또 DEM과 같이 공부한다면 쉬워요

제가 또 이해하기 쉽게 예와 함께 들고올게요.

 

정비소에서 "현재 DTC 뭐야?", "DTC 삭제해줘"라는 명령을
ECU가 어떻게 이해하고 처리하는지 또 쉽고 이해하기 쉽게 가르쳐 드리겠습니다.