본문 바로가기
자동차 소프트웨어

ECU Sleep/WakeUp 완벽 정리: 차량 전력 관리 및 저전력 아키텍처 실무 가이드

by 버그없는토마토 2026. 1. 15.

ECU Sleep/WakeUp 완벽 정리: 차량 전력 관리 및 저전력 아키텍처 실무 가이드

Sleep이란? WakeUp이란?


들어가며

자동차 배터리는 한정된 자원입니다.

주행을 안하고 방치하게 되면 방전이 되어 곤란한 상황이 생기기 마련이죠...

가솔린 차는 연료가 있지만, 전기차는 배터리 용량이 곧 주행거리입니다

100kWh 배터리라고 해도 사용 가능한 에너지는 정해져 있다는 말이죠

 

그런데.... 생각해봅시다.

 

차량이 파킹 중인데...

모든 ECU가 깨어있다면?

차량이 주차 중...

엔진 ECU: 활성 (클럭 100MHz, 전력 5W)
변속기 ECU: 활성 (3W)
배터리 관리 시스템: 활성 (2W)
인포테인먼트: 활성 (15W)
조명 제어: 활성 (1W)
바디 제어: 활성 (2W)
진단 시스템: 활성 (1W)
...

총 전력: 30W (가만히 있는데도!)

24시간 방치:
30W × 24시간 = 720Wh = 0.72kWh 낭비!

1개월:
0.72 × 30 = 21.6kWh (월간 손실)

1년:
21.6 × 12 = 259.2kWh (연간 손실!)

이는 약 1500km의 주행거리에 해당한다.

전기차 사용자: "엥? 왜 방치했는데 배터리가 50%에서 45%로 떨어졌어?"

이 문제를 해결하는 것이 ECU Sleep/Wake입니다

차량이 필요 없을 때 ECU를 "잠들게" 해서 전력을 거의 사용하지 않게 되죠.

필요할 때 "깨워서" 즉시 동작하게 합니다

실무 중에서 슬립/웨이크업은 제가 생각하기에 가장 중요하다고 생각합니다
왜냐하면 방전과 관련이 되어있기 떄문에 가장 크리티컬하다고 생각해요

이 글에서는 ECU Sleep/Wake의 원리, 메커니즘, 실무 구현법, 그리고 성능 분석을 정리해보겠습니다

예시를 곁들인.

 

제일 이슈가 많이나고 제일 중요한 부분이라고 할 수 있어요.
개념 바로 잡고 실무에 투입되어 봅시다!!

1. ECU Sleep/Wake란?

1.1 정의

Sleep/Wake = ECU의 전력 상태를 동적으로 관리하여 전력 소비를 최소화하면서도 필요할 때 즉시 동작하도록 하는 기술

ECU의 두 가지 상태:

┌─────────────────────────────────┐
│ ACTIVE (Wake) 상태              │
├─────────────────────────────────┤
│ - 클럭 동작 (100% 주파수)       │
│ - 모든 회로 활성                 │
│ - 메모리 접근 가능               │
│ - 입출력 처리 가능               │
│ - 전력 소비: 최대 (5~10W)       │
│ - 응답 시간: < 1ms             │
│                                 │
│ 사용 시기: 주행 중, 엔진 작동   │
└─────────────────────────────────┘
           ↕ (트리거)
┌─────────────────────────────────┐
│ SLEEP 상태                       │
├─────────────────────────────────┤
│ - 클럭 감소 또는 중단            │
│ - 대부분 회로 비활성             │
│ - 메모리는 유지 (상태 보존)      │
│ - 외부 이벤트 대기               │
│ - 전력 소비: 최소 (mW 단위)     │
│ - 응답 시간: 1~100ms           │
│                                 │
│ 사용 시기: 주차, 정차, 대기     │
└─────────────────────────────────┘

1.2 Sleep/Wake vs 다른 기술

항목 Sleep/Wake Hibernation Power Off
상태 보존 ✓ (메모리 유지) ✓ (디스크 저장) ✗ (상태 손실)
Wake-up 시간 빠름 (1~100ms) 느림 (초 단위) 느림 (부팅)
전력 소비 매우 낮음 극도로 낮음 0W
데이터 손실 없음 없음 모두 손실
비용
사용 시기 대기, 정차 장시간 미사용 차량 폐기

1.3 왜 필요한가?

[1] 배터리 수명 연장
────────────────────
Active 모드: 30W 소비
Sleep 모드: 0.3W 소비
→ 100배 전력 절감!

[2] 전기차의 주행거리
────────────────────
주행 시간: 1시간
주행 거리: 400km

주차 시간: 23시간
Sleep 모드: 상태 유지
주행거리 손실: 최소화 (1km 미만)

[3] 환경 보호
─────────────
연료 절감 = CO2 감소
배터리 방전 방지 = 교체 주기 연장

[4] 사용자 만족도
──────────────────
"왜 방치했는데 배터리가 떨어져?" → 해결!
"시동 걸릴 때 응답이 느려" → 해결!

2. 전력 관리의 중요성

2.1 자동차의 전력 구조

자동차의 전원 시스템:

┌─────────────────────────────────┐
│ 12V 배터리 (Engine 보조)         │
├─────────────────────────────────┤
│ - 시동 모터 (스타터)             │
│ - 조명 (헤드라이트, 실내등)      │
│ - 와이퍼, 에어컨                 │
│ - ECU 백업 전원                  │
│                                 │
│ 용량: 50~100Ah (600~1200Wh)    │
└─────────────────────────────────┘


┌─────────────────────────────────┐
│ 고전압 배터리 (HEV/EV 구동용)    │
├─────────────────────────────────┤
│ - 모터 구동                      │
│ - 충전 시스템                    │
│ - 급속 제동                      │
│                                 │
│ 용량: 50~100kWh (극도로 큼)    │
└─────────────────────────────────┘


┌─────────────────────────────────┐
│ 각 ECU (12V 공급)               │
├─────────────────────────────────┤
│ Engine ECU: 3~5W (주행 중)     │
│           : 0.3W (Sleep)       │
│                                 │
│ Transmission ECU: 2~4W         │
│ Battery Mgmt: 2~5W             │
│ Infotainment: 10~20W           │
│ Body Control: 1~3W             │
│ ...등 30~40개                  │
└─────────────────────────────────┘

2.2 전력 소비 패턴

24시간 동안의 차량 전력 소비:

시간:     전력     상태          설명
────────────────────────────────────────
00:00   0.5W   SLEEP            주차 중, 모두 Sleep
02:00   0.5W   SLEEP
04:00   0.5W   SLEEP
        ↓
08:00   25W    PRE-WAKE         운전자 접근 감지
        ↓      (부분 깨우기)
08:05   100W   WAKE             시동 준비
        ↓
08:10   500W   CRANKING         엔진 시동
        ↓
08:15   1500W  RUNNING          주행 시작
08:20   2000W  HIGH LOAD        가속, 오르막
09:00   1500W  DRIVING
        ↓
17:00   1200W  DRIVING
        ↓
18:00   1500W  TRAFFIC JAM      정체, 정차 빈번
        ↓
18:15   100W   IDLING           정차 대기
        ↓
18:30   25W    PRE-SLEEP        시동 끔
        ↓
18:35   0.5W   SLEEP            다시 주차

결과:
- Active: ~10시간 (평균 1500W)
- Idle/Traffic: ~2시간 (평균 100W)
- Sleep: ~12시간 (평균 0.5W)

일일 에너지:
- Active: 10 × 1500 = 15,000Wh = 15kWh
- Idle: 2 × 100 = 200Wh
- Sleep: 12 × 0.5 = 6Wh
─────────────────────────────
총합: ~15.2kWh

만약 Sleep이 없다면:
24 × 30W = 720Wh = 0.72kWh (손실!)

3. Sleep/Wake 메커니즘

3.1 전력 절감 기법

ECU가 전력을 줄이는 방법:

[1] Clock Gating (클럭 차단)
───────────────────────────

정상 작동:
┌──────────────────────┐
│ Crystal Oscillator   │ → 100MHz
├──────────────────────┤
│ PLL (Phase Lock Loop)│ → 100MHz
├──────────────────────┤
│ CPU                  │ (매 클럭마다 스위칭 손실)
├──────────────────────┤
│ Memory               │ (전력 소비!)
└──────────────────────┘

Clock Gating 적용:
┌──────────────────────┐
│ Oscillator           │ → 꺼짐
├──────────────────────┤
│ PLL                  │ → 꺼짐
├──────────────────────┤
│ CPU                  │ → 클럭 없음 (동작 중지)
├──────────────────────┤
│ Memory               │ → 대기 상태 (최소 전력)
└──────────────────────┘

전력 감소: 50~80%


[2] Power Gating (전원 차단)
──────────────────────────

회로 일부를 완전히 끈다:

Power Domain:
┌──────────────────────┐
│ CPU Core    │ 전원 끔
│ FPU         │ 전원 끔
├──────────────────────┤
│ SRAM        │ 유지 (상태 보존)
├──────────────────────┤
│ Wake Unit   │ 활성 (깨어있음)
└──────────────────────┘

전력 감소: 80~95%
(Leakage Current만 남음)


[3] Dynamic Voltage and Frequency Scaling (DVFS)
──────────────────────────────────────────────

전압과 주파수를 조정:

활성 모드:
├─ 주파수: 100MHz
├─ 전압: 1.8V
└─ 전력: P = CV²f (제곱 관계!)

절감 모드:
├─ 주파수: 50MHz (50% 감소)
├─ 전압: 1.2V (67% 감소)
└─ 전력: 약 25% 수준

이유: 전력은 전압의 제곱에 비례!
P ∝ V²
감소 폭이 매우 크다!

3.2 Sleep 상태 계층 (C-States)

자동차 ECU의 전력 상태 계층:

┌─────────────────────────────────────────┐
│ C0: ACTIVE (완전 활성)                  │
├─────────────────────────────────────────┤
│ 클럭:    100%                           │
│ 전압:    1.8V                           │
│ 메모리: 모두 활성                       │
│ 입출력: 가능                            │
│ 전력:   5~10W                          │
│ 대기:   < 1ms                          │
│ 사용:   주행 중, 엔진 작동             │
└─────────────────────────────────────────┘
           ↓ (조건: RPM > 500)
┌─────────────────────────────────────────┐
│ C1: Light Sleep (경량 절감)             │
├─────────────────────────────────────────┤
│ 클럭:    50%                            │
│ 전압:    1.5V                           │
│ 메모리: 모두 활성                       │
│ 입출력: 가능 (응답 빠름)               │
│ 전력:   2~3W                           │
│ 대기:   1~5ms                          │
│ 사용:   정차 대기, 신호                │
└─────────────────────────────────────────┘
           ↓ (조건: 신호 대기 > 30초)
┌─────────────────────────────────────────┐
│ C2: Deep Sleep (깊은 절감)              │
├─────────────────────────────────────────┤
│ 클럭:    0% (중단)                      │
│ 전압:    1.0V                           │
│ 메모리: 핵심만 활성 (SRAM 유지)        │
│ 입출력: 제한됨 (이벤트 기반)           │
│ 전력:   0.3~0.5W                       │
│ 대기:   10~50ms                        │
│ 사용:   주차 상태                      │
└─────────────────────────────────────────┘
           ↓ (조건: 주차 > 2시간)
┌─────────────────────────────────────────┐
│ C3: Hibernation (절대절감)              │
├─────────────────────────────────────────┤
│ 클럭:    0% (꺼짐)                      │
│ 전압:    최소                           │
│ 메모리: Flash에 저장 (Power Off)       │
│ 입출력: 최소 (시동 버튼만)             │
│ 전력:   0.05W (Leakage만)              │
│ 대기:   초 단위                        │
│ 사용:   장시간 주차 (휴가)             │
└─────────────────────────────────────────┘

4. Wake-up 트리거

4.1 Wake-up 신호 종류

ECU를 깨우는 신호들:

[1] CAN 메시지 (가장 일반적)
────────────────────────

상황: 차량 파킹, Engine ECU Sleep

Gateway ECU: "엔진을 시동하라!"
            (CAN 메시지 전송)
                ↓
Engine ECU: 인터럽트 발생
            (CAN 트랜시버가 감지)
                ↓
             깨어남! (Wake)
                ↓
            즉시 시동 준비


[2] 외부 인터럽트 (GPIO)
─────────────────────

예시:
- 문 열림 센서: 도어 오픈 → 조명 켜기
- 가속 페달: 발을 올렸다 내림 → 엔진 준비
- 브레이크 페달: 밟음 → 제동 시스템 활성
- 시동 버튼: 누름 → 시동


[3] 타이머 (Periodic Wake)
──────────────────────────

주기적으로 깨우기:

1시간마다 깨어나기:
└─ Battery Management System 점검
└─ 배터리 온도 확인
└─ 충전 상태 확인
└─ 진단 코드 스캔

목적: 장시간 주차 중 배터리 상태 모니터링


[4] 이벤트 기반
───────────────

특정 이벤트 발생:
- 배터리 전압 저하
- 온도 이상
- 보안 침입 감지
- 예약된 작업 시간

4.2 Wake-up 프로세스

Engine ECU가 깨어나는 과정:

[Step 1] Wake 신호 감지
─────────────────────

상태: C2 (Deep Sleep)
└─ 클럭: 꺼짐
└─ 전압: 1.0V
└─ 전력: 0.3W

이벤트: CAN 메시지 도착
└─ CAN 트랜시버: "메시지 받았다!"
└─ 인터럽트 신호 발생


[Step 2] 부분 깨우기 (Pre-wake)
───────────────────────────────

타이밍: 0~10ms

상태: C2 → C1
└─ 클럭 제어기: 활성화 시작
└─ 전압 레귤레이터: 1.0V → 1.5V
└─ 메모리: 준비 시작


[Step 3] 완전 깨우기 (Full wake)
────────────────────────────────

타이밍: 10~50ms

상태: C1 → C0
└─ 클럭: 100% 주파수로 복구
└─ 전압: 1.8V로 상향
└─ 모든 회로: 활성화
└─ 메시지 처리: 시작


[Step 4] 작업 수행
──────────────────

타이밍: 50ms 이후

└─ CAN 메시지 처리
└─ 필요한 작업 수행
└─ 응답 전송


[Step 5] Sleep 복귀
──────────────────

작업 완료 후, 일정 시간 활동 없으면:
└─ C0 → C1: 클럭 감소
└─ C1 → C2: 전원 절감
└─ 다시 Sleep 상태로


총 소요 시간: 1~100ms (타입에 따라 다름)

5. CAN 통신과 Sleep

5.1 Sleep 중 CAN 메시지 수신

문제: ECU가 Sleep 중인데 CAN 메시지가 도착하면?

상황:
├─ Engine ECU: C2 (Deep Sleep, 클럭 꺼짐)
├─ CAN 버스: 계속 신호 전달
└─ Gateway ECU: "엔진 시동하라!" (메시지 전송)

해결책: CAN 트랜시버의 "Wake" 기능

┌────────────────────────────────────────┐
│ CAN 트랜시버 (항상 활성!)             │
├────────────────────────────────────────┤
│                                        │
│ CAN 버스 ──→ 신호 감지                │
│                ↓                      │
│           메시지 필터링               │
│                ↓                      │
│   특정 메시지? (Wake-up 메시지?)     │
│   ┌────────────┬────────────┐         │
│   YES         NO                     │
│   │            │                      │
│   ▼            ▼                      │
│ 인터럽트   무시 (작동 안 함)         │
│ 신호                                 │
│   │                                  │
│   ▼                                  │
│ ECU 깨우기                           │
│                                        │
└────────────────────────────────────────┘


CAN 필터링 규칙 예시:

Wake 메시지:
├─ Message ID: 0x100 (Engine Command)
├─ DLC: 8
├─ Data[0]: 0x01 (시동 명령)

Non-Wake 메시지 (무시):
├─ 진단 메시지
├─ 텔레메트리 데이터
├─ 상태 정보

5.2 Selective Wake-up

Selective Wake-up (선택적 깨우기):

목표: 필요한 메시지만으로 깨우기
      불필요한 메시지는 무시

설정 항목:

┌──────────────────────────────────────┐
│ 1. Message ID 필터                   │
├──────────────────────────────────────┤
│ 깨울 조건:                           │
│ - 0x100: Engine Command             │
│ - 0x200: Transmission Command       │
│ - 0x300: Brake Command              │
│                                      │
│ 깨우지 않을 조건:                    │
│ - 0x500: Diagnostics (Sleep 무시)  │
│ - 0x600: Telemetry (Sleep 무시)    │
└──────────────────────────────────────┘

┌──────────────────────────────────────┐
│ 2. Data Byte 필터                    │
├──────────────────────────────────────┤
│ Message 0x100이어도:                │
│                                      │
│ Data[0] = 0x01 (시동) → Wake!      │
│ Data[0] = 0x02 (상태) → 무시        │
└──────────────────────────────────────┘

┌──────────────────────────────────────┐
│ 3. 시간 기반 필터                    │
├──────────────────────────────────────┤
│ 운전 시간 (6:00~22:00):            │
│ └─ 모든 Wake 메시지 활성             │
│                                      │
│ 야간 (22:00~6:00):                 │
│ └─ 긴급 메시지만 활성                │
└──────────────────────────────────────┘

결과:
✓ Sleep 중 불필요한 깨우기 감소
✓ 전력 소비 추가 절감
✓ 응답성 유지

6. 구현 코드

6.1 Sleep 모드로 진입

// ECU를 Sleep 모드로 진입
#include <stdint.h>

typedef enum {
    ECU_STATE_ACTIVE = 0,      // C0: 완전 활성
    ECU_STATE_LIGHT_SLEEP = 1, // C1: 경량 절감
    ECU_STATE_DEEP_SLEEP = 2,  // C2: 깊은 절감
    ECU_STATE_HIBERNATION = 3  // C3: 절대절감
} ECU_PowerState_t;

typedef struct {
    ECU_PowerState_t current_state;
    uint32_t idle_time_ms;
    uint8_t can_wakeup_enabled;
    uint32_t wakeup_mask;  // 어떤 CAN 메시지로 깨울지
} ECU_PowerManager_t;

ECU_PowerManager_t power_mgr = {
    .current_state = ECU_STATE_ACTIVE,
    .idle_time_ms = 0,
    .can_wakeup_enabled = 1,
    .wakeup_mask = 0x00000100  // CAN ID 0x100만 깨우기
};

// 10ms 주기로 호출되는 함수
void PowerManager_MainFunction(void) {
    static uint32_t idle_counter = 0;

    // RPM 확인: 엔진이 돌고 있나?
    uint16_t current_rpm = Engine_GetRPM();

    if (current_rpm > 500) {
        // 엔진 작동 중: Active 상태 유지
        power_mgr.current_state = ECU_STATE_ACTIVE;
        idle_counter = 0;
        return;
    }

    // 엔진 끔: 타이머 증가
    idle_counter++;
    power_mgr.idle_time_ms = idle_counter * 10;  // 10ms 단위

    // 상태 전환 로직
    if (power_mgr.idle_time_ms < 5000) {
        // 5초 미만: Active 유지
        power_mgr.current_state = ECU_STATE_ACTIVE;
        return;
    }

    if (power_mgr.idle_time_ms < 30000) {
        // 5초 ~ 30초: Light Sleep
        if (power_mgr.current_state != ECU_STATE_LIGHT_SLEEP) {
            PowerManager_EnterLightSleep();
        }
        power_mgr.current_state = ECU_STATE_LIGHT_SLEEP;
        return;
    }

    if (power_mgr.idle_time_ms < 120000) {
        // 30초 ~ 2분: Deep Sleep
        if (power_mgr.current_state != ECU_STATE_DEEP_SLEEP) {
            PowerManager_EnterDeepSleep();
        }
        power_mgr.current_state = ECU_STATE_DEEP_SLEEP;
        return;
    }

    // 2분 이상: Hibernation
    if (power_mgr.current_state != ECU_STATE_HIBERNATION) {
        PowerManager_EnterHibernation();
    }
    power_mgr.current_state = ECU_STATE_HIBERNATION;
}

// Light Sleep 진입 함수
void PowerManager_EnterLightSleep(void) {
    // Step 1: 진행 중인 작업 완료
    WaitForAllTasksComplete();

    // Step 2: 상태 저장
    SaveSystemState();

    // Step 3: 클럭 감소 (100MHz → 50MHz)
    ClockManager_SetFrequency(50000000);  // 50MHz

    // Step 4: 전압 감소 (1.8V → 1.5V)
    VoltageRegulator_SetVoltage(1500);  // 1.5V

    // Step 5: CAN Wake-up 활성화
    CAN_EnableSelectiveWakeup(power_mgr.wakeup_mask);

    // Step 6: CPU Wait For Interrupt
    CPU_WaitForInterrupt();  // CPU가 대기 (저전력)

    // Step 7: 인터럽트 발생 시 복귀
    // (자동으로 다음 줄부터 실행)
}

// Deep Sleep 진입 함수
void PowerManager_EnterDeepSleep(void) {
    // Step 1: 모든 작업 완료
    WaitForAllTasksComplete();

    // Step 2: 상태 메모리에 저장
    SaveSystemState();

    // Step 3: 클럭 완전 차단
    ClockManager_Disable();

    // Step 4: 전압 최소화 (1.0V)
    VoltageRegulator_SetVoltage(1000);  // 1.0V

    // Step 5: 주변 장치 비활성화
    PeripheralManager_DisableAll();

    // Step 6: CAN 트랜시버만 활성 (Wake-up용)
    CAN_SetLowPowerWakeupMode(power_mgr.wakeup_mask);

    // Step 7: 극저전력 대기
    CPU_WaitForEvent();  // 최소 전력 대기

    // Step 8: Wake 신호 도착 시 복귀
    // (여기서부터 실행 재개)
}

// Wake 신호 처리 (인터럽트 핸들러)
void CAN_WakeupInterruptHandler(void) {
    // Step 1: Wake 신호 확인
    if (CAN_IsWakeupMessage() != TRUE) {
        return;  // 거짓 경고 무시
    }

    // Step 2: 클럭 복구
    ClockManager_SetFrequency(100000000);  // 100MHz

    // Step 3: 전압 복구
    VoltageRegulator_SetVoltage(1800);  // 1.8V

    // Step 4: 상태 복구
    RestoreSystemState();

    // Step 5: 타이머 초기화
    idle_counter = 0;
    power_mgr.idle_time_ms = 0;

    // Step 6: 정상 작업 재개
    power_mgr.current_state = ECU_STATE_ACTIVE;
}

6.2 CAN Selective Wake-up 설정

// CAN 필터링으로 선택적 Wake-up 구현
#include <string.h>

typedef struct {
    uint32_t message_id;
    uint8_t data_mask[8];      // 확인할 바이트 마스크
    uint8_t data_pattern[8];   // 매칭할 데이터 패턴
    uint8_t enabled;           // 활성화 여부
} CAN_WakeupFilter_t;

#define MAX_WAKEUP_FILTERS 10

CAN_WakeupFilter_t wakeup_filters[MAX_WAKEUP_FILTERS] = {
    // Filter 0: Engine Command (ID 0x100)
    {
        .message_id = 0x100,
        .data_mask = {0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
        .data_pattern = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
        // Data[0] = 0x01 (시동) 매칭
        .enabled = 1
    },

    // Filter 1: Transmission Command (ID 0x200)
    {
        .message_id = 0x200,
        .data_mask = {0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
        .data_pattern = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
        .enabled = 1
    },

    // Filter 2: Brake Command (ID 0x300)
    {
        .message_id = 0x300,
        .data_mask = {0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
        .data_pattern = {0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
        .enabled = 1
    },
};

// CAN 메시지를 받았을 때: Wake 여부 판단
uint8_t CAN_IsWakeupMessage(void) {
    CAN_Frame_t received_msg;

    // CAN 메시지 수신
    if (CAN_Receive(&received_msg) != OK) {
        return FALSE;
    }

    // 각 필터와 비교
    for (int i = 0; i < MAX_WAKEUP_FILTERS; i++) {
        if (wakeup_filters[i].enabled == 0) {
            continue;  // 비활성화된 필터 스킵
        }

        // Message ID 매칭?
        if (received_msg.id != wakeup_filters[i].message_id) {
            continue;
        }

        // Data 매칭? (마스크 적용)
        uint8_t match = 1;
        for (int j = 0; j < 8; j++) {
            uint8_t masked_data = received_msg.data[j] & wakeup_filters[i].data_mask[j];
            uint8_t expected_data = wakeup_filters[i].data_pattern[j];

            if (masked_data != expected_data) {
                match = 0;
                break;
            }
        }

        if (match == 1) {
            // 모두 매칭됨! → Wake!
            return TRUE;
        }
    }

    // 매칭된 필터 없음 → 무시
    return FALSE;
}

7. 성능 분석

7.1 전력 소비 비교

실제 측정 데이터:

상태              전력      설명
──────────────────────────────────────────
ACTIVE (C0)      8W       주행 중, 엔진 작동
Light Sleep (C1) 2.5W     신호 대기
Deep Sleep (C2)  0.4W     주차 상태
Hibernation (C3) 0.05W    장시간 주차

하루 (24시간) 에너지 소비:

시나리오 1: Sleep 없이 항상 ACTIVE
────────────────────────────
24시간 × 8W = 192Wh = 0.192kWh (낭비!)

시나리오 2: 적절한 Sleep 관리
────────────────────────────
Active (8시간):   8h × 8W = 64Wh
Light Sleep (4시간): 4h × 2.5W = 10Wh
Deep Sleep (12시간): 12h × 0.4W = 4.8Wh
─────────────────────────────
합계: 78.8Wh (전력 절감: 59%!)


1개월 절감 효과:

Sleep 없음: 0.192 × 30 = 5.76kWh
Sleep 있음: 0.0788 × 30 = 2.36kWh
──────────────────────────
월간 절감: 3.4kWh

1년 절감 효과:
3.4 × 12 = 40.8kWh (약 300km 주행거리)


전기차 기준:
배터리: 60kWh
1년 절감: 40.8kWh / 60kWh = 68% 배터리 방전 방지!

7.2 Wake-up 지연시간

Wake-up 응답 시간 측정:

상태          Wake-up 신호    완전 깨우기    처리 개시
─────────────────────────────────────────────────────
C1 (Light)    ← 1ms      → 5ms         → 8ms
C2 (Deep)     ← 2ms      → 25ms        → 30ms
C3 (Hiber)    ← 10ms     → 1000ms      → 1000ms


실무에서의 영향:

CAN 메시지 도착 → Engine ECU 처리

상황 1: Light Sleep (1ms 대기)
└─ 응답 지연: 8ms (거의 무시할 수준)
└─ 사용자 체감: 없음

상황 2: Deep Sleep (2ms 대기)
└─ 응답 지연: 30ms (경미)
└─ 사용자 체감: 거의 없음

상황 3: Hibernation (10ms 대기)
└─ 응답 지연: 1000ms (1초, 눈에 띔!)
└─ 사용자 체감: "응답 느려" (배터리 매우 낮을 때만 사용)

8. 자주 하는 실수

8.1 Sleep 중 타임아웃

잘못된 예:
// Sleep 중 타이머가 작동 안 함
Sleep();
wait_for_timeout(1000);  // 1초 대기 예상
// ...하지만 Sleep 중엔 클럭이 안 돌아!

문제:
- 1000ms 타이머가 영원히 대기
- 시스템 행(Hang) 발생
- 응답 불가능

올바른 예:
// RTC (Real Time Clock) 사용 (Sleep 중에도 작동)
Rtc_SetAlarm(1000);  // 1초 후 깨우기
Sleep();
// 1초 후 자동으로 Wake-up 신호

8.2 Wake-up 신호 손실

잘못된 예:
// CAN 필터 설정 없음
CAN_SetWakeupMode(TRUE);  // 무작정 활성화
// 모든 CAN 메시지로 깨워짐!

문제:
- 불필요한 메시지로도 깨움
- 지속적인 깨우기/자기 반복
- Sleep 이점 사라짐 (전력 낭비)

올바른 예:
// 선택적 Wake-up 설정
CAN_SetSelectiveWakeup(0x100);  // ID 0x100만
CAN_SetSelectiveWakeup(0x200);  // ID 0x200만
// 필요한 메시지만 깨움

8.3 상태 복구 오류

잘못된 예:
void PowerManager_EnterSleep(void) {
    // 상태 저장 안 함!
    ClockManager_Disable();
    CPU_WaitForInterrupt();
}

void CAN_WakeupHandler(void) {
    ClockManager_Enable();
    // 상태 복구 안 함!
    // 변수들의 값이 모두 초기화됨!
}

문제:
- 변수 값이 사라짐
- 시스템 상태 불일치
- 예측 불가능한 동작

올바른 예:
void PowerManager_EnterSleep(void) {
    SaveSystemState();  // 상태 저장!
    ClockManager_Disable();
    CPU_WaitForInterrupt();
}

void CAN_WakeupHandler(void) {
    ClockManager_Enable();
    RestoreSystemState();  // 상태 복구!
    // 정상 동작 재개
}

9. 핵심 정리

ECU Sleep/Wake:
- ECU의 전력 상태를 동적으로 관리
- 불필요할 때 절전, 필요할 때 즉시 깨우기

필요성:
- 배터리 수명 연장
- 전기차 주행거리 증대
- 환경 보호 (전력 절감)
- 사용자 만족도 향상

메커니즘:
- Clock Gating: 클럭 차단 (50~80% 절감)
- Power Gating: 전원 차단 (80~95% 절감)
- DVFS: 전압/주파수 조정 (75% 절감)

상태 계층:
- C0 ACTIVE: 100% (5~10W)
- C1 Light Sleep: 50% 클럭 (2~3W)
- C2 Deep Sleep: 0% 클럭 (0.3~0.5W)
- C3 Hibernation: 최소 (0.05W)

Wake-up 트리거:
- CAN 메시지
- 외부 인터럽트 (버튼, 센서)
- 타이머 (주기적)
- 이벤트 기반

CAN Wake-up:
- Selective Wake-up: 필요한 메시지만
- 메시지 필터링: ID, Data 기반
- 전력 추가 절감

성능:
- 월간 절감: ~3.4kWh (40%)
- Wake-up 지연: 5~30ms (무시할 수준)
- 응답성 유지 (1ms 이하 추가 지연)

주의사항:
- Sleep 중 타이머 작동 안 함 (RTC 사용)
- Wake-up 신호 필터링 필수
- 상태 저장/복구 필수
- 멀티코어 동기화 필요