36940db938a8f4a1e919496793ed439850a221c2다. 아래 경로는 각 기능을 켜고 SoC·보드·드라이버가 해당 훅을 구현했을 때의 구조다. 도식의 장치 A·B·C와 시간은 설명용이며 실기 전력·지연 측정값이 아니다.1. CPU, 시스템, 장치는 서로 다른 질문에 답한다
CPU가 당장 실행할 스레드를 찾지 못하면 idle thread가 돈다. CONFIG_PM=y이면 그 시점에 시스템 전력 정책이 CPU/SoC 상태를 제안할 수 있다. 장치 PM은 또 다른 층이다. 시스템 절전에 맞춰 한꺼번에 장치를 처리할 수도 있고, CPU가 계속 실행 중이어도 각 장치의 사용 횟수로 suspend할 수도 있다. idle 진입 = 장치 suspend로 읽으면 설정과 드라이버 조건을 놓친다.
| 구성 | 판단·동작 | 추가 전제 |
|---|---|---|
CONFIG_PM | idle 중 시스템 전력 상태를 고르고 진입을 시도 | v3.7.0 Kconfig는 HAS_PM과 시스템 클록을 요구; 플랫폼 상태·훅 필요 |
CONFIG_PM_DEVICE | 드라이버 PM action 인터페이스 제공 | 드라이버별 action callback이 있어야 실제 하드웨어 동작 |
CONFIG_PM_DEVICE_SYSTEM_MANAGED | 시스템 저전력 상태로 갈 때 대상 장치를 suspend/resume | CONFIG_PM_DEVICE 아래 선택, 실제 경로에는 시스템 PM 진입 필요 |
CONFIG_PM_DEVICE_RUNTIME | 장치별 사용 횟수의 0↔1 경계에서 suspend/resume | 개별 장치의 runtime PM 활성화와 드라이버 action 필요 |
근거: System PM, Device PM, Runtime PM, subsys/pm/Kconfig 5–17행과 83–153행.
2. idle thread의 기본 대기와 PM 상태 진입을 구분한다
v3.7.0의 kernel/idle.c는 idle 반복에서 다음 timeout을 보고 pm_system_suspend()를 시도한다. PM이 꺼져 있거나 상태 선택이 ACTIVE로 끝나면 일반 k_cpu_idle()로 이어진다. 상태를 골랐더라도 시스템 관리 장치 suspend가 실패하면 PM 진입을 취소하고 역시 일반 idle로 간다. PM 상태에 실제 진입하면 pm_state_set()이 SoC 상태 전환을 맡고, 복귀 훅과 통지 절차가 뒤따른다. 둘 다 CPU가 쉬는 경로지만 동일한 상태나 절전 깊이를 보장하지 않는다.
↔ 좁은 화면에서는 흐름을 좌우로 이동해 읽으세요.
pm_state_set()으로 SoC 저전력 상태 요청.k_cpu_idle() 사용. PM 정책·시스템 관리 장치 suspend를 뜻하지 않는다.k_cpu_idle().이 그림은 함수 호출의 선택 관계를 요약한다. ISR에서 시작되는 복귀 처리와 SoC별 실제 대기 명령은 간략화했다.
따라서 CONFIG_PM=y만 보고 깊은 sleep을 기대해서는 안 된다. pm_state_force()로 지정한 상태는 해당 진입에서 기본 정책 선택을 건너뛴다. 아래 시간·lock 필터는 기본 정책을 통한 선택에 관한 설명이다. 보드가 상태를 제공해야 하고, 그 상태에서 살아 있는 wake source를 애플리케이션이 마련해야 한다. SMP에서는 CPU별 PM 상태를 다루며, 모든 CPU의 장치를 매 CPU마다 suspend하는 구조도 아니다.
근거: kernel/idle.c 28–75행, subsys/pm/pm.c 120–201행, 3.7.0 System PM 설명.
3. 정책은 ‘남은 시간’만 보지 않는다
기본 residency 정책은 CPU에 정의된 상태를 살펴보고 최소 체류 시간 + 복귀 지연이 다음 사건까지의 시간에 들어오는지 검사한다. 상태 lock과 최대 허용 latency도 걸러낸다. 그래서 타이머가 멀리 있어도 잠긴 상태에는 들어갈 수 없고, 상태가 하나도 적합하지 않으면 ACTIVE로 남는다. 애플리케이션 정의 정책은 pm_policy_next_state()를 구현하는 다른 선택이다.
| 확인 | 기본 정책의 판정 | 실기에서 볼 자료 |
|---|---|---|
| 플랫폼 상태 목록 | 정의되지 않은 절전 상태는 선택하지 못함 | 보드/SoC devicetree의 power state |
| 체류·복귀 시간 | 남은 시간 ≥ 최소 체류 + exit latency | 다음 timeout, min-residency-us, exit-latency-us |
| 상태 lock·latency | 잠금 중이거나 exit latency가 지정 한도 이상인 상태는 건너뜀 | pm_policy_state_lock_get() 사용처와 latency 요청 |
| 장치 busy | CONFIG_PM_NEED_ALL_DEVICES_IDLE=y이면 기본 정책이 전체 busy를 먼저 검사. 단, v3.7.0에서는 PM_DEVICE && !SMP에 의존하여 SMP에서는 선택할 수 없음 | 최종 .config·pm_device_busy_set/clear() 균형 |
근거: 3.7.0 정책 문서, subsys/pm/policy.c 216–281행, subsys/pm/Kconfig 47–52행.
4. 시스템 관리 장치 PM은 시스템 상태와 함께 움직인다
CONFIG_PM_DEVICE_SYSTEM_MANAGED=y인 경로는 선택된 CPU 저전력 상태가 장치 PM을 요구할 때 장치를 역초기화 순서로 suspend하고, 복귀하면서 반대 순서로 resume를 호출한다. 의존성이 초기화 순서에 맞아야 하는 이유다. v3.7.0은 runtime PM이 활성화된 장치, wakeup 활성 장치, busy 장치 등을 이 순회에서 건너뛴다. -ENOSYS·-ENOTSUP·-EALREADY는 건너뛰는 예외다. 그 밖의 음수 오류로 드라이버의 suspend action이 실패하면 이미 suspend된 장치에 역순 resume를 시도하고 CPU PM 진입을 취소한다. 이 복귀 함수는 각 resume 반환값을 검사하지 않으므로 실제 장치 재개 성공은 드라이버 상태·로그로 따로 확인해야 한다.
↔ 좁은 화면에서는 세 장치 열을 좌우로 이동해 읽으세요.
A→B→C는 순서 설명용이다. 실제 순회는 준비 상태, busy, wakeup, runtime 활성 여부를 보고 일부 장치를 건너뛰며, 드라이버에서 오류가 나면 진입을 취소한다.
| 조건 | v3.7.0 경로 | 결과 |
|---|---|---|
| 선택 상태가 장치 PM 제외 | PM_STATE_RUNTIME_IDLE이면 항상 생략. 그 밖의 상태도 zephyr,pm-device-disabled가 있으면 생략 | 시스템 상태는 들어가도 장치 순회는 없을 수 있음 |
| runtime PM 활성 장치 | 시스템 관리 순회에서 건너뜀 | 장치 자신의 get/put 계약으로 상태 유지 |
| busy·wakeup 활성 장치 | 장치 순회에서 건너뜀 | 전체 busy 검사 옵션은 PM_DEVICE && !SMP에서만 선택 가능; SMP는 그 옵션으로 진입을 막지 못함 |
| 건너뛰기 예외 외의 suspend 음수 오류 | 이미 멈춘 대상에 역순 resume 호출 시도 | 이번 시스템 상태 진입 취소. resume 반환값은 이 경로에서 무시되므로 실제 재개 여부 별도 확인 |
| SMP의 동시 idle | 마지막 활성 CPU가 장치 suspend, 첫 복귀 CPU가 resume | CPU마다 같은 장치 action을 반복하지 않음 |
근거: 3.7.0 Device PM 문서, device_system_managed.c 27–75행, pm.c 82–98행과 150–162행.
5. runtime PM은 ‘지금 이 장치를 쓰는가’를 센다
CONFIG_PM_DEVICE_RUNTIME=y는 시스템 idle 여부와 별개로 장치의 사용 횟수를 센다. 개별 장치도 pm_device_runtime_enable() 또는 zephyr,pm-device-runtime-auto로 활성화되어야 한다. 첫 get()은 필요하면 resume하고, 중첩된 get은 장치를 계속 활성 상태로 두며, 마지막 put()은 suspend한다. 동기식 put은 완료를 기다린다. put_async()는 커널 시작 후 일반(non-ISR-safe) 장치에서는 suspend 작업을 예약하지만, ISR-safe 장치는 동기 경로를 쓰고 pre-kernel 문맥에서는 async 요청이 동기로 강제된다. 그러므로 API 성공·실제 상태·타이밍을 구별해 관찰한다.
↔ 좁은 화면에서는 시간 단계를 좌우로 이동해 읽으세요.
초기 suspended는 runtime PM이 성공적으로 활성화된 장치의 일반 모델이다. 커널 시작 후 non-ISR-safe 장치의 async put은 SUSPENDING을 지나며 작업 실행 시점이 달라진다. ISR-safe와 pre-kernel 경로는 동기 처리한다.
| 사건 | 코어가 하는 일 | 주의 |
|---|---|---|
| runtime enable | 장치별 runtime 제어 시작 | 전역 Kconfig만으로 모든 장치가 자동 활성화되지는 않음 |
| 첫 get / 마지막 put | 사용 횟수 경계에서 드라이버 RESUME / SUSPEND action | 반환값 확인, get/put 짝 맞추기 |
| put_async | 커널 시작 후 non-ISR-safe 장치는 usage 0에서 suspend 작업 예약 | ISR-safe 장치는 즉시 동기 처리, pre-kernel은 async=false로 강제. 예약 경로에서 즉시 완료 단정 금지 |
| 시스템 상태 전환 | runtime 활성 장치를 system-managed 순회에서 제외 | 장치가 active인 채 플랫폼 깊은 절전으로 가도 안전한지 따로 설계 |
근거: 3.7.0 Runtime PM 문서, device_runtime.c 46–83행, 166–230행과 285–370행.
6. 전원 도메인과 일반 의존성을 같은 자동화로 보지 않는다
센서가 버스를 거쳐 동작한다면 센서와 버스의 수명도 맞춰야 한다. Zephyr 3.7.0 문서는 runtime PM이 일반 장치 간 의존성은 자동 관리하지 않는다고 명시한다. 필요하면 드라이버가 의존 장치를 직접 get/put한다. 예외적으로 CONFIG_PM_DEVICE_POWER_DOMAIN=y이고 devicetree의 power-domain 관계가 있으며 자식과 도메인 모두 runtime PM이 활성화된 경우, 자식의 runtime get/put이 도메인 get/put을 시도한다. 자식 runtime PM이 꺼져 있으면 get은 이 연쇄 이전에 반환한다. 도메인 드라이버의 action callback과 wakeup 경로도 별도로 갖춰야 한다.
| 관계 | 3.7.0에서의 책임 | 검증할 것 |
|---|---|---|
| 센서 → 버스처럼 일반 의존성 | 사용하는 드라이버가 상위/의존 장치의 get/put 순서를 직접 관리 | 자식 사용 중 부모가 잠들지 않는지 |
자식 → power-domain | CONFIG_PM_DEVICE_POWER_DOMAIN=y, DT 관계, 자식 runtime 활성화가 있을 때 도메인 get/put 시도 | 도메인 runtime 활성화, action callback·wakeup 설계, 오류 반환 |
| 깊은 시스템 절전 → 장치 전원 손실 | 필요하면 CONFIG_PM_POLICY_DEVICE_CONSTRAINTS와 상태 lock 사용 | 작업 중 손실되는 상태를 정책이 제외하는지 |
wakeup-source 선언은 능력을 나타내며, v3.7.0은 초기화만으로 기능을 켜지 않는다. 필요할 때 pm_device_wakeup_enable()을 호출하고 드라이버·SoC가 해당 절전 상태에서 실제 깨움 신호를 유지하는지 확인한다. 자식 장치를 wake source로 쓴다면 그 전원 도메인도 wakeup 상태로 설정할 책임이 드라이버 또는 애플리케이션에 있다.근거: Runtime PM 의존성 주의, Power Domain의 wakeup 주의, Device PM wakeup·제약, subsys/pm/Kconfig 101–108행, device_runtime.c 15–20행과 166–223행.
7. 보드에서 재현할 때 확인할 기록
- Zephyr commit, 보드·SoC, 최종
.config의PM·PM_DEVICE·PM_DEVICE_SYSTEM_MANAGED·PM_DEVICE_RUNTIME를 같이 남긴다. - devicetree의 CPU power state와 체류/exit latency,
zephyr,pm-device-disabled, wakeup source를 상태별로 확인한다. - 시스템 idle 경로에서 선택된 상태, 실제
pm_state_set()진입, 복귀 통지와 유효한 wake event를 따로 기록한다. - 장치별 runtime 활성화 여부, get/put 사용 횟수, action callback 성공/실패, system-managed 순회 대상 여부를 나눠 본다.
- 버스·전원 도메인·자식 장치의 의존 수명과 드라이버가 직접 관리하는 get/put 순서를 검사한다.
이 글은 구조를 설명한다. CONFIG_PM=y 또는 장치 callback 하나만으로 특정 보드의 전력 절감량, 복귀 시간, wakeup 성공을 보증하지 않는다.
8. 고정 버전 근거와 설명의 경계
공식 문서의 일반 계약과 같은 commit의 구현 분기를 함께 확인했다. 도식은 원본 설명용이며, SoC별 pm_state_set() 구현·하드웨어 측정·모든 드라이버 action을 실기 검증한 결과는 아니다.