본문 바로가기
AUTOSAR 심화

AUTOSAR Dcm 완벽 이해: 진단 통신의 모든 것

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

AUTOSAR Dcm 완벽 이해: 진단 통신의 모든 것

DCM이란?

DCM이란?

들어가며

안녕하세요 버그없는토마토입니다

지난 게시물에서 Dem이 어떻게 오류를 감지하고 DTC를 생성하는지 배웠죠?

Dem을 통해 고장을 판단했고 DTC를 생성하여 저장을 했습니다

 

그럼 이제 "그 DTC를 정비소에 어떻게 전달할까?"를 배워야 할 차례예요.

정비소에서 진단기(스캔툴)를 자동차에 연결하면, "DTC 읽어줘", "DTC 삭제해줘"라는 명령을 보내요.

누가 이 명령을 받고 처리할까?

답은 Dcm (Diagnostic Communication Manager)이에요.

 

밑에 이해하기 쉽게 예를 보여드릴게요

실제 정비소 장면:

정비사: "DTC 스캔 시작!"
진단기: CAN 버스에 명령 전송
        "읽어줄 수 있어?"

↓

ECU (Dcm):
"내가 받았어! 
Dem에게 현재 DTC 뭐냐고 물어볼게"

↓

Dem: "P0117이 있어요"

↓

Dcm: "응! DTC P0117을 진단기에 전송!"

↓

진단기 화면: "P0117: O2 Sensor Low Voltage"
정비사: "아! O2 센서를 교체해야겠네"

이 모든 통신을 담당하는 게 Dcm이에요!

이 DCM과 DEM에 관해 안다면 사실 자동차 소프트웨어에서 진단 코드들이

어떤 생태계에서 어떤 프로세스로 돌아가는지 다 안다고 볼 수 있는데요

코드는 다 잘 안다고 가정하고!나면 DTC관련해서 개념싸움은 이제 끝입니다.

 

면접에서든 대화에서든 어떤 질문이 들어와도 철벽 방어 가능하죠.

 

그럼 본론으로 돌아와 이번 글에서는 Dcm이 정확히 뭔지, UDS 프로토콜이 뭔지,
정비소와 어떻게 통신하는지
상세히 설명해보겠습니다.


📡 Dcm이란?

Dcm의 정의

Dcm = Diagnostic Communication Manager

자동차 ECU에서 정비소의 진단기와 통신하는 시스템이에요.

Dcm의 역할 (3가지)

1️⃣ 진단 요청 수신 (Diagnostic Request Reception)
   └─ 진단기의 명령을 CAN으로 받기
   └─ "DTC 읽어줄래?", "DTC 삭제해줄래?" 등

2️⃣ Dem/NvM과 협력 (Cooperation with Dem/NvM)
   └─ Dem: DTC 조회
   └─ NvM: DTC 삭제

3️⃣ 진단 응답 전송 (Diagnostic Response Transmission)
   └─ 진단기에 결과 회신
   └─ "여기 P0117 있습니다" 등

Dcm vs 다른 모듈

| 모듈 | 역할 | 통신 상대 | 예시 |
|------|------|---------|------|
| Dem | 오류 감지·관리 | Dcm | "P0117 있어" |
| NvM | 데이터 저장 | Dcm | "DTC 삭제" |
| Dcm | 정비소 통신 | 진단기 | "P0117 전송!" |

협력 관계:
진단기 ↔ Dcm ↔ Dem ↔ NvM
                    ↑
            플래시 메모리

🔌 UDS: Unified Diagnostic Services

UDS란?

UDS = ISO 14229-1 표준 진단 프로토콜

자동차 진단을 위해 세계적으로 표준화된 통신 방식이에요.

UDS의 구조

UDS 메시지 구조:

┌─────────────────────────────────┐
│ CAN 메시지 (물리 계층)           │
├─────────────────────────────────┤
│ Service ID (1바이트)             │ 0x22: ReadDataByIdentifier
│ + Parameters (0~N 바이트)        │ + DataIdentifier
│ + Data (0~N 바이트)              │ + [실제 데이터]
└─────────────────────────────────┘

예시:
Service ID: 0x22 (ReadDataByIdentifier)
Parameter: 0xF1 0x86 (DataID: Engine Speed)
Data: [응답] 0x0B 0xB8 (2844 rpm)

주요 UDS 서비스

1️⃣ 0x19: ReadDTC (DTC 읽기)
   ─────────────────
   목적: 현재 저장된 모든 DTC 조회

   요청:
   Service ID: 0x19
   SubFunction: 0x01 (현재 DTC)

   응답:
   0x59 (Positive Response)
   DTC 1: 0x01, 0x17, 0x00 (P0117)
   DTC 2: 0x01, 0x30, 0x00 (P0130)

   용도: 정비소에서 "현재 고장이 뭔가?" 확인

2️⃣ 0x14: ClearDiagnosticInformation (DTC 삭제)
   ─────────────────
   목적: 저장된 DTC 모두 삭제

   요청:
   Service ID: 0x14
   GroupOfDTC: 0xFF FF FF (모든 DTC)

   응답:
   0x54 (Positive Response)

   용도: 센서 교체 후 DTC 초기화

3️⃣ 0x22: ReadDataByIdentifier (데이터 읽기)
   ─────────────────
   목적: 특정 데이터 읽기 (실시간)

   요청:
   Service ID: 0x22
   DataIdentifier: 0xF1 0x86 (엔진 속도)

   응답:
   0x62 (Positive Response)
   Data: 0x0B 0xB8 (2844 rpm)

   용도: 실시간 값 확인 (RPM, 온도 등)

4️⃣ 0x10: DiagnosticSessionControl (세션 제어)
   ─────────────────
   목적: 진단 모드 진입/해제

   세션 종류:
   0x01: DefaultSession (기본)
   0x03: ExtendedDiagnosticSession (확장)
   0x10: SafetySystemDiagnosticSession (안전)

   확장 진단 세션:
   - 더 많은 데이터 접근 가능
   - 보안 수준이 낮음 (비밀번호 필요할 수도)

5️⃣ 0x3E: TesterPresent (연결 유지)
   ─────────────────
   목적: 진단기가 여전히 연결되어 있음을 알림

   요청:
   Service ID: 0x3E
   SubFunction: 0x00

   응답:
   0x7E (Positive Response)

   용도: 타임아웃 방지 (매 1초마다 전송)

UDS 응답 코드

Positive Response (성공):
0x5F = Service ID + 0x40
예: 0x19 요청 → 0x59 응답

Negative Response (실패):
0x7F (Negative Response)
+ Service ID
+ NRC (Negative Response Code)

NRC 종류:
0x31: Request Out of Range
      (요청이 범위를 벗어남)

0x33: Security Access Denied
      (보안 인증 실패)

0x12: Sub-function Not Supported
      (지원하지 않는 서브함수)

0x24: Request Sequence Error
      (요청 순서 오류)

🔄 Dcm의 상태 머신

Dcm은 4가지 세션 상태를 관리해요.

┌──────────────────────┐
│  DEFAULT_SESSION     │ (기본 상태)
│  - 진단 불가        │
│  - 일반 작동         │
└──────────┬───────────┘
           │
   진단기 연결 요청 (0x10, 0x03)
           │
           ▼
┌──────────────────────┐
│EXTENDED_DIAGNOSTIC   │ (확장 진단)
│SESSION               │
│ - DTC 읽기 가능     │
│ - DTC 삭제 가능     │
│ - 데이터 읽기 가능  │
└──────────┬───────────┘
           │
   타임아웃 또는 명시적 해제 (0x10, 0x01)
           │
           ▼
┌──────────────────────┐
│  DEFAULT_SESSION     │ (복귀)
│  - 진단 불가        │
│  - 일반 작동         │
└──────────────────────┘

세션 타임아웃

진단기가 연결 후 아무 명령도 보내지 않으면:

시간: 0s
Dcm: EXTENDED_SESSION (진단 모드)

시간: 0.5s
진단기: 0x3E (TesterPresent) 전송
Dcm: "아직 있구나" (타이머 리셋)

시간: 1.0s
진단기: 0x3E 전송
Dcm: "계속 있구나"

...

시간: 5.0s
진단기: 명령 없음!
Dcm: "타임아웃! DEFAULT_SESSION 복귀"
↓
DTC 읽기 불가능!

→ 정비기는 자동으로 0x3E를 매초 전송

📡 Dcm API (Application Programming Interface)

주요 API들

1️⃣ Dcm_Init
   ─────────────────────────
   목적: Dcm 초기화

   호출 시점: 시스템 부팅 시

   역할:
   - 세션을 DEFAULT_SESSION으로 설정
   - 진단 파라미터 초기화
   - CAN 메시지 리스너 등록

2️⃣ Dcm_GetSessionState
   ─────────────────────────
   목적: 현재 진단 세션 상태 조회

   선언:
   Std_ReturnType Dcm_GetSessionState(
       Dcm_SessionType* SessionState
   );

   사용 예:
   Dcm_SessionType current_session;
   Dcm_GetSessionState(&current_session);

   if (current_session == DCM_EXTENDED_SESSION) {
       // 진단 모드 중
       // 일부 기능 제한
   }

   반환값:
   DCM_DEFAULT_SESSION: 기본
   DCM_EXTENDED_SESSION: 확장 진단
   DCM_SAFETY_SESSION: 안전

3️⃣ Dcm_GetSecurityLevel
   ─────────────────────────
   목적: 현재 보안 레벨 조회

   용도:
   - 일부 서비스는 보안 레벨이 높아야 함
   - 예: 프로그래밍은 레벨 3 필요

   사용 예:
   uint8 sec_level;
   Dcm_GetSecurityLevel(&sec_level);

   if (sec_level < 3) {
       // 프로그래밍 불가 (권한 부족)
   }

4️⃣ Dcm_DslInit
   ─────────────────────────
   목적: CAN 통신 초기화

   역할:
   - CAN 메시지 버퍼 설정
   - 타이머 시작
   - 요청/응답 메커니즘 준비

5️⃣ Dcm_MainFunction
   ─────────────────────────
   목적: Dcm 메인 루프

   호출 주기: 10ms 또는 100ms

   역할:
   - CAN 메시지 수신 확인
   - UDS 서비스 처리
   - 응답 전송
   - 타이머 관리 (세션 타임아웃)

   의사 코드:
   void Dcm_MainFunction(void) {
       if (CAN_message_received) {
           service_id = message[0];

           if (service_id == 0x19) {
               Handle_ReadDTC();
           } else if (service_id == 0x14) {
               Handle_ClearDTC();
           } else if (service_id == 0x22) {
               Handle_ReadData();
           }
           ...

           Send_Response_To_CAN();
       }

       if (session_timeout) {
           Switch_To_DefaultSession();
       }
   }

🔗 Dcm과 다른 모듈의 협력

Dcm ↔ Dem (오류 관리)

정비기 명령: "DTC 읽어줄래?"

Dcm 처리:
1️⃣ 수신: CAN에서 0x19 서비스 메시지 수신
2️⃣ 파싱: Service ID = 0x19 (ReadDTC)
3️⃣ 요청: Dem_GetEventStatus() 호출
         Dem_GetDTCOfEvent() 호출
4️⃣ 응답 구성:
   - 0x59 (Positive Response)
   - + DTC들 (P0117, P0130, ...)
5️⃣ 전송: CAN 버스로 진단기에 전송

진단기 수신:
"P0117 있네요!"

Dcm ↔ NvM (메모리 관리)

정비기 명령: "DTC 삭제해줄래?"

Dcm 처리:
1️⃣ 수신: CAN에서 0x14 서비스 메시지 수신
2️⃣ 파싱: Service ID = 0x14 (ClearDTC)
3️⃣ 확인: "보안 레벨이 충분한가?"
4️⃣ 요청: Dem_ClearDTC() 호출
         → Dem이 내부적으로 
            NvM_EraseNvBlock(DTC_Block) 호출
5️⃣ 대기: NvM이 플래시 삭제 완료 대기 (약 100ms)
6️⃣ 응답 구성:
   - 0x54 (Positive Response)
7️⃣ 전송: CAN 버스로 진단기에 전송

진단기 수신:
"DTC 삭제 완료!"

📊 정비소 진단 시나리오 (완전)

시나리오: O2 센서 고장 진단 및 복구

[상황]
자동차: O2 센서 고장 → P0117 DTC 저장됨
사용자: "Check Engine 경고등이 켜있어요"
정비사: "진단해보겠습니다"

─────────────────────────────────────

[1단계] 정비소 진단기 연결
시간: 0ms
정비사: "스캔 시작!"
진단기: CAN에 연결 신호 전송

─────────────────────────────────────

[2단계] Dcm이 진단 세션 시작
시간: 10ms
진단기: CAN ID 0x600 메시지 전송
        [0x10, 0x03]  (DiagnosticSessionControl, Extended)

ECU (Dcm):
Dcm이 수신 → 상태 전환
DEFAULT_SESSION → EXTENDED_SESSION

─────────────────────────────────────

[3단계] DTC 읽기
시간: 20ms
진단기: CAN ID 0x600 메시지 전송
        [0x19, 0x01]  (ReadDTC, CurrentDTC)

ECU (Dcm):
1. 수신
2. Dem_GetEventStatus() 호출
3. Dem이 응답: "P0117이 있습니다"
4. 응답 구성:
   [0x59, 0x01, 0x17, 0x00] (P0117)
5. CAN ID 0x601 메시지로 회신

진단기 화면:
"P0117: Engine Coolant Temperature Sensor"
"O2 Sensor Low Voltage"

정비사: "아, O2 센서 교체해야겠네요"

─────────────────────────────────────

[4단계] 실시간 데이터 확인
시간: 50ms
진단기: CAN ID 0x600 메시지 전송
        [0x22, 0xF1, 0x86]  (ReadDataByIdentifier, EngineSpeed)

ECU (Dcm):
1. 수신
2. 현재 엔진 속도 값 조회
   현재 rpm = 1000
3. 응답 구성:
   [0x62, 0xF1, 0x86, 0x03, 0xE8]  (1000 rpm)
4. CAN ID 0x601 메시지로 회신

진단기 화면:
"현재 엔진 속도: 1000 rpm"

정비사: "엔진은 돌고 있네, O2 센서가 맞네요"

─────────────────────────────────────

[5단계] TesterPresent 주기적 전송
시간: 1000ms부터 매 1초마다
진단기: [0x3E, 0x00]  (TesterPresent)
ECU (Dcm): 
응답: [0x7E, 0x00]
(타이머 리셋, 세션 유지)

─────────────────────────────────────

[6단계] 정비사가 O2 센서 교체

시간: 60초
정비사: "센서 교체 완료!"
자동차 재시동

ECU:
1. Dem_Init()
2. NvM_ReadBlock(DTC_Block)
3. DTC P0117은 여전히 있음
   → TENTATIVE_PASSED (한 번은 통과)

─────────────────────────────────────

[7단계] DTC 삭제 명령
시간: 70초
진단기: CAN ID 0x600 메시지 전송
        [0x14, 0xFF, 0xFF, 0xFF]  (ClearDTC, AllDTC)

ECU (Dcm):
1. 수신
2. 보안 레벨 확인 (진단기 연결 = OK)
3. Dem_ClearDTC() 호출
4. Dem이 NvM_EraseNvBlock(DTC_Block) 호출
5. NvM이 플래시에서 DTC 삭제 (약 50ms)
6. 응답 구성:
   [0x54]  (ClearDiagnosticInformation_Response)
7. CAN ID 0x601 메시지로 회신

진단기 화면:
"DTC 삭제 완료!"

ECU:
- Dem: 상태 초기화 (PASSED)
- NvM: DTC 블록 비워짐
- "Check Engine" 경고등 꺼짐!

─────────────────────────────────────

[8단계] 진단 세션 종료
시간: 80초
진단기: [0x10, 0x01]  (DefaultSession)

ECU (Dcm):
EXTENDED_SESSION → DEFAULT_SESSION
진단 모드 해제

─────────────────────────────────────

[완료]
정비사: "수리 완료했습니다!"
사용자: "감사합니다!"
차량: 정상 작동 ✓

⚙️ Dcm 설정 (ARXML)

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

        <!-- 진단 서비스: ReadDTC -->
        <DIAGNOSTIC-SERVICE>
          <SHORT-NAME>ReadDTC</SHORT-NAME>
          <SERVICE-ID>0x19</SERVICE-ID>
          <ENABLED>true</ENABLED>
          <SUPPORTED-SESSIONS>
            <SESSION>EXTENDED_DIAGNOSTIC_SESSION</SESSION>
            <SESSION>SAFETY_SYSTEM_SESSION</SESSION>
          </SUPPORTED-SESSIONS>
          <SECURITY-LEVEL>1</SECURITY-LEVEL>
        </DIAGNOSTIC-SERVICE>

        <!-- 진단 서비스: ClearDTC -->
        <DIAGNOSTIC-SERVICE>
          <SHORT-NAME>ClearDTC</SHORT-NAME>
          <SERVICE-ID>0x14</SERVICE-ID>
          <ENABLED>true</ENABLED>
          <SUPPORTED-SESSIONS>
            <SESSION>EXTENDED_DIAGNOSTIC_SESSION</SESSION>
          </SUPPORTED-SESSIONS>
          <SECURITY-LEVEL>1</SECURITY-LEVEL>
        </DIAGNOSTIC-SERVICE>

        <!-- 진단 서비스: ReadDataByIdentifier -->
        <DIAGNOSTIC-SERVICE>
          <SHORT-NAME>ReadDataByIdentifier</SHORT-NAME>
          <SERVICE-ID>0x22</SERVICE-ID>
          <ENABLED>true</ENABLED>
          <SUPPORTED-SESSIONS>
            <SESSION>DEFAULT_SESSION</SESSION>
            <SESSION>EXTENDED_DIAGNOSTIC_SESSION</SESSION>
          </SUPPORTED-SESSIONS>
          <SECURITY-LEVEL>0</SECURITY-LEVEL>
          <DATA-IDENTIFIERS>
            <DATA-ID>
              <ID>0xF1 0x86</ID>
              <NAME>EngineSpeed</NAME>
              <LENGTH>2</LENGTH>
            </DATA-ID>
            <DATA-ID>
              <ID>0xF1 0x87</ID>
              <NAME>EngineTemperature</NAME>
              <LENGTH>1</LENGTH>
            </DATA-ID>
          </DATA-IDENTIFIERS>
        </DIAGNOSTIC-SERVICE>

        <!-- 세션 설정 -->
        <DIAGNOSTIC-SESSION>
          <SHORT-NAME>DefaultSession</SHORT-NAME>
          <SESSION-ID>0x01</SESSION-ID>
          <TIMEOUT>10000</TIMEOUT> <!-- ms -->
        </DIAGNOSTIC-SESSION>

        <DIAGNOSTIC-SESSION>
          <SHORT-NAME>ExtendedDiagnosticSession</SHORT-NAME>
          <SESSION-ID>0x03</SESSION-ID>
          <TIMEOUT>5000</TIMEOUT> <!-- ms -->
        </DIAGNOSTIC-SESSION>

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

🎯 면접 예상 질문 10가지

Q1: Dcm이 뭐고, 왜 필요해요?
A: "Dcm은 정비소 진단기와 통신하는 시스템입니다. 
   UDS 프로토콜을 사용해서 DTC 읽기, 삭제, 
   실시간 데이터 조회 등을 처리합니다."

Q2: UDS 프로토콜이 뭐예요?
A: "ISO 14229-1 표준 진단 프로토콜입니다. 
   0x19 (ReadDTC), 0x14 (ClearDTC), 0x22 (ReadData) 
   같은 서비스 ID를 사용해 통신합니다."

Q3: 주요 UDS 서비스는 몇 개나 되나요?
A: "핵심은 5가지입니다. ReadDTC(0x19), ClearDTC(0x14), 
   ReadDataByIdentifier(0x22), DiagnosticSessionControl(0x10), 
   TesterPresent(0x3E)입니다."

Q4: 진단 세션이 뭐죠?
A: "진단기가 연결된 상태를 관리하는 방식입니다. 
   DEFAULT_SESSION은 진단 불가, 
   EXTENDED_SESSION은 DTC 읽기/삭제 가능합니다."

Q5: 세션 타임아웃은 왜 필요한가요?
A: "진단기가 연결되었지만 실제로 작동하지 않을 수 있으니까요. 
   타이머가 만료되면 자동으로 DEFAULT_SESSION으로 돌아가 
   차량의 일반 작동을 보호합니다."

Q6: TesterPresent는 뭐하는 건가요?
A: "진단기가 여전히 연결되어 있음을 ECU에 알리는 신호입니다. 
   매초 전송해서 세션 타임아웃을 방지합니다."

Q7: Dcm과 Dem은 어떻게 협력하나요?
A: "진단기에서 DTC 읽기 명령이 오면, 
   Dcm이 Dem_GetEventStatus()를 호출해 
   현재 DTC를 조회합니다."

Q8: DTC를 삭제할 때 어떤 일이 일어나나요?
A: "Dcm이 0x14 서비스를 받으면, 
   Dem_ClearDTC()를 호출합니다. 
   내부적으로 Dem이 NvM_EraseNvBlock()을 호출해 
   플래시의 DTC를 삭제합니다."

Q9: 보안 레벨이 뭐죠?
A: "일부 서비스는 높은 권한이 필요합니다. 
   DTC 읽기는 레벨 1, 프로그래밍은 레벨 3 같은 식으로 
   서비스마다 필요한 레벨이 다릅니다."

Q10: ReadDataByIdentifier(0x22)로 뭘 할 수 있나요?
A: "엔진 속도, 온도, 센서값 같은 실시간 데이터를 
   조회할 수 있습니다. 진단기가 현재 자동차 상태를 
   모니터링할 때 사용합니다."

정리: Dcm의 핵심

항목 설명
정의 정비소 진단기와 통신
프로토콜 UDS (ISO 14229-1)
주요 서비스 ReadDTC, ClearDTC, ReadData, SessionControl
세션 DEFAULT (진단 불가), EXTENDED (진단 가능)
타임아웃 일정 시간 명령 없으면 DEFAULT_SESSION 복귀
Dem 협력 DTC 읽기/삭제
NvM 협력 DTC 플래시 삭제
보안 서비스별 보안 레벨

마치며

이제 Dcm이 어떻게 정비소와 통신하는지 알게되셨나요?

정비소라고 표현했지만 개발과정이라면 진단기라고 생각해도 똑같고

그게 아니라면 캐노이라고 생각해도 무방하죠

저희는 NvM, Dem, Dcm을 통해 자동차 고장 진단의 완전한 흐름을 배웠어요:

고장 발생
   ↓
Dem이 감지 → DTC 생성
   ↓
NvM이 저장 → 플래시에 기록
   ↓
Dcm이 통신 → 정비소에 전송
   ↓
정비사가 교체 → DTC 삭제

여러분!! 여러분은 지금 DTC 생태계를 마스터 하신거예요 

그것도 게시물 3개로 말이죠!

이제 더이상 가르쳐드릴게 없어요... 하산하세요...(농담입니다)

 

아직 배고프시죠?

그럼 다음 게시물로 또 새로운 정보를 떠먹여드릴게요

다음 편에서는 "AUTOSAR CanIf 완벽 이해: CAN 메시지 라우팅의 모든 것"을 다뤄보겠습니다.

CAN 메시지가 어떻게 올바른 ECU로 전달되고,
어떻게 필터링되고, 어떻게 우선순위가 정해지는지
상세하게 설명해드릴게요

그리고 그림을 통해 또 이해하기 쉽게 가져와 보겠습니다.