SOFTWARE POWER MANAGEMENT

가정에서 전기요금 고지서를 받았을 때 그 전기요금이 부과되기까지 내가 얼마나 전기를 쓰고 있는 지를 한 번 따져 본 적이 있는가? 보통 우리는 계량기를 통해 자신이 지난 달 얼마만큼의 전기를 사용했는지 쉽게 알 수 있다. 이러한 개념과 같은 것이 전원 관리자(Power Man-ager)이다. Windows CE에서의 효과적인 전원 관리는 전원 관리자를 얼마나 효율적으로 다루는가에 달려 있다고 해도 과언은 아니다. 이 글에서는 모바일/임베디드 개발자들에게 좀 더 효율적인 전원 관리 기법을 소개하고자 한다.Windows CE에서의 전원 관리 구조Windows CE 관련 모바일/임베디드 개발자라면 전원 관리 구조에 대해 잘 알고 있어야 한다(그림 1). Windows CE의 전원 관리는 PM.DLL이라고 하는 전원 관리자가 맡고 있다.먼저 하나의 응용 프로그램은 전원에 관계된 인터럽트로 I/O 컨트롤 모델의 통지 메시지를 전원 관리자에게 전달하거나, 전원 관리자 API를 사용하여 디바이스 드라이버에게 현재 전원의 상태를 알려준다. 따라서 디바이스 드라이버 개발자들에게 전원 관리자와 응용 프로그램 사이에 전원 관리자 API를 두어 더욱 더 유연하게 디바이스 드라이버를 개발할 수 있도록 해주는 장점을 가진다.좀 더 상세히 들어가 보면, 전원 관리 API는 커널 레벨과 디바이스 드라이버의 사용자 레벨로 나눌 수 있다. 커널 레벨의 전원 관리는 수행될 쓰레드가 없을 때 부르는 OEMIdle() 함수와 시스템을 일시 중지(Suspend)할 때 호출하는 OEMPowerOff() 함수로 구현된다. 예를 들어, PDA의 전원 버튼이 눌러졌을 때 불러진다. 또한 한 가지 더 선택적으로 구현 가능한 커널 함수로써 pOEM UpdateReschedule Time 시스템 Tick 간격을 조정할 때 호출한다. 한편, 사용자 레벨의 전원 관리 함수들은 XXX_PowerUp()와 XXX_Down()으로 전원을 켜고 끌 수 있다. Windows CE 5.0 Platform Builder를 가진 독자가 있다면 PUBLICCOMMONOAK DRIVERSPMTESTDEVSAMPLE 폴더에 있는 DevicePowerNotify 예제 소스를 참조하기 바란다.이 XXX_PowerUp/Down 함수는 드라이버의 일시 정지/재시작(Suspend/ Resume) 때 장치 관리자에 호출되는데, 전원 관리자와는 무관하지만 반드시 디바이스 드라이버 개발자들이 구현해야 한다. 그리고 선택적으로 구현해야 할 함수는 IOCTL_POWER_XXX와 Device PowerNotify() 함수이다.IOCTL_POWER_XXX 함수는 전원 관리자가 드라이버의 전원 상태를 묻거나 제어할 때 사용한다. 또한 DevicePower Notify() 함수는 디바이스 드라이버가 전원 관리자에게 전원 상태의 변경을 알릴 때 사용한다. 참고로 표 1에 응용 프로그램 레벨 전원 관리의 함수를 제시한다.전원 관리의 내부에서 OAL 소스 코드 분석구체적으로 전세계적으로 가장 많이 사용되고 있는 Pocket PC와 Smartphone에서의 전원 소비가 어떻게 구현되는지 알아보도록 하자.전원 관리의 내부에서는 OAL(OEM Adaption Layer)의 OEMPowerOff 함수와 OEMIdle() 함수가 가장 중요하다.첫째, OEMPowerOff() 함수는 시스템을 일시 정지시키며 전원 소비를 최저로 만드는 역할을 한다. 이 함수가 호출되면 DRAM은 셀프-리프레시(Self-Referesh) 상태로 변경되고 CPU가 멈춘다. 이 때 인터럽트는 평소에는 멈춰 있으나 시스템을 깨울(Wakeup) 인터럽트가 걸리면 시스템 상태가 OEMPowerOff 진입 이전 상태로 복원된다.둘째, OEMIdle() 함수는 수행될 쓰레드가 없을 때 스케줄러에 의해 호출되는데, CPU의 전원 모드를 저전력 모드로 변경한다. CPU에 따라 다르며 각 CPU의 전원 관련 레지스터를 변경해야 한다.또한 저전력 모드와 일반 모드의 변경은 신속히 변경 가능해야 하며 DRAM을 셀프-리프레시 모드로 넣는 것은 불가능하다. 그런 후 인터럽트에 의해 깨어나서 바로 다음 동작이 수행 가능해야 한다.셋째, OEMIdle() 함수의 경우 CPU가 멈추고 인터럽트가 발생할 때까지 인터럽트는 대기하고 있다. 인터럽트가 발생되면 인터럽트 서비스 루틴(ISR, Interrupt Service Routine)이 수행된다. OEMIdle 내부의 CPU가 멈추고 이 후 코드를 수행하고 스케줄러의 OEMIdle 이후 코드 진행 다음 쓰레드가 수행된다. 소스 2를 보면 OEMIdle() 함수가 어떻게 실행되는 지 알 수 있다.OEMIdle() 함수에서의 시스템 Tick 인터럽트는 보통 1ms 간격으로 호출된다. 그런 후 Tick ISR은 dwResched Time을 검사하여 SYSINTR_NOP 또는 SYSINTR _RESCHED 값을 되돌려준다. 만약, 이때 SYSINTR_NOP를 호출하면 스케줄러가 바로 OEMIdle 함수를 호출하고 SYSINTR _RESCHED를 호출하면 다음 수행할 쓰레드가 실행된다. 또한 스케줄러는 pOEM Update ReschedTime를 불러 시스템 틱 간격(System Tick Clock)을 조정한다. 그런 후 다음 쓰레드가 수행될 시간에 근거하여 부르게 된다. 물론 이론적으로 Tick ISR은 SYSINTR _NOP으로 리턴 할 일이 없지만 CPU 클록이 더 오랫동안 멈추게 되어 평균 전원 소비량이 감소하는 현상이 발생된다. 이러한 스케줄러를 가변 틱 스케줄러(Variable Tick Scheduler)라고 부른다. 스케줄러에 대해 더 자세히 알고 싶다면 privatewinceos coreosnkkernel 디렉토리 내의 schedule.c 소스를 살펴보기 바란다.전원 관리의 핵심, 전원 관리자전원 관리자는 응용 프로그램과 Windows CE 커널 간의 전원 관리에 대하여 중계자 역할을 수행한다. 이것은 미리 정의된 시스템 전원 상태를 관리하고 디바이스 드라이버와 응용 프로그램에게 그 상태값을 넘겨주거나 받는 역할을 한다.또한 시스템 전원 상태는 디바이스가 가질 수 있는 최대 전원 상태를 설정할 수 있으며 디바이스 드라이버는 스스로 전원을 제어할 수 있는 서비스를 제공한다. 응용 프로그램은 디바이스가 가질 수 있는 최소 전원 상태를 정의할 수 있다(참고로 표 2는 디바이스 전원 상태를 나타낸다).이러한 디바이스 전원 상태는 Pocket PC의 경우 모든 전원 상태를 사용하며 Smartphone은 suspend/resume 상태로 들어가지 않는다. Unattended 상태의 경우 오디오 드라이버는 D4 전원 상태 코드를 가진다.전원 관리의 예제 소스는 WINCE500 PUBLICCOMMONOAKDRIVERSPMPDDDEFAULT 디렉토리의 소스를 살펴보기 바란다. 여기는 다양한 형태의 전원 관리 기능을 제공하며 WINCE500 PUBLICCOMMONOAKDRIVERSPMPDDPDA에서는 윈도우 모바일 장치의 전원 관리에 사용된다. PM.DLL의 함수는 (PmSetSystemPowerState = SetSystemPowerState)와 같이 각각 PM API와 연결된다.전원 디바이스 드라이버의 역할그렇다면 전원 디바이스 드라이버는 어떤 역할을 하는 지 알아보도록 하자. 전원 디바이스 드라이버는 디바이스가 지원하는 전원 상태를 전원 관리자(PM)에 알리고 전원 관리자(PM)에서 오는 전원 변경 요청을 처리한다. 다시 말해 디바이스의 전원을 켜고 끄는 역할을 하며 디바이스의 인터럽트를 깨우고 인터럽트의 이벤트를 처리한다.이때 디바이스 인터페이스는 디바이스 인터페이스 클래스를 가지는데, IClass 레지스트리 키는 PM.DLL에 PM 인터페이스가 지원됨을 알려준다. PM.H에 보면 소스 3과 같이 4개의 표준 IClass GUID가 정의되어 있다.전원 관리자와 디바이스 드라이버의 통신은 전원 관리자가 IOCTL을 통해 드라이버와 통신한다. 반대로 디바이스 드라이버는 DevicePowerNotify를 통해 전원 관리자와 통신한다. 다시 말해 Device PowerNotify() 함수는 디바이스 드라이버가 스스로 자신의 전원 상태를 변경하기 위해 사용된다. 디바이스 드라이버는 자신의 전원 상태를 변경하고자 할 때 DevicePowerNotify를 통해 전원 관리자에게 요청한다. 전원 관리자는 현재 변경 가능한 지 판단한 후 IOCTL_POWER _SET를 통해 드라이버에 전원 상태 변경을 요청한다.응용 프로그램 API마지막으로 사용자가 직접 눈으로 전원 상태를 확인할 수 있는 응용 프로그램 API에 대해 알아보도록 하겠다. 응용 프로그램 API는 전원 관리자 API와 전원 통지 API의 두 가지로 나뉘는데, 전원 관리자 API는 시스템이나 디바이스의 전원 상태를 설정하거나 알아보기 위해 사용된다. 이것은 수동적으로 전원을 관리하는 것으로써, 사용자가 제어판에서 직접 전원을 관리한다. 또한 전원 알림 API는 전원 관련 이벤트를 받기 위해 사용되거나 전원 관련 이벤트는 전원 관리자나 드라이버의 요청에 의해 발생한다. 가령 독자들 중 PMP나 PDA를 사용하다가 전원이 부족하다는 메시지나 경고음을 듣게 될 때가 있을 텐데, 이러한 역할을 구현해 주는 것이 응용 프로그램 API들이다. 그림 3은 Windows CE의 제어판에서 전원 관리를 하는 화면이다.요약Windows CE의 효율적인 전원 관리는 실제 동작 중 전원을 줄이기 위해서는 빠르게 PLL를 내리고 올리는 데 약 10ms의 시간이 필요한데, 다시 할 수 없기 때문에 인터럽트가 처리되는 시간에 재빠르게 실행시키고자 하는 목적이 있다. 또한 이러한 것을 구현하는 개발자들은 사용자 또는 어떠한 시스템 인터럽트가 걸렸을 때 전원 관리자와 디바이스 드라이버, 응용 프로그램 간의 구조에 대해 잘 알고 있어야 한다.아직도 수많은 모바일/임베디드 개발자가 Windows CE의 소스가 공개되어 있는지 모르는 사람들이 많다. 이 Windows CE 소스는 공유 소스(Shared Source) 방식으로 Platform Builder라는 개발도구 평가판을 다운로드 받아서 설치하면 된다.
회원가입 후 이용바랍니다.
개의 댓글
0 / 400
댓글 정렬
BEST댓글
BEST 댓글 답글과 추천수를 합산하여 자동으로 노출됩니다.
댓글삭제
삭제한 댓글은 다시 복구할 수 없습니다.
그래도 삭제하시겠습니까?
댓글수정
댓글 수정은 작성 후 1분내에만 가능합니다.
/ 400
내 댓글 모음
저작권자 © 테크월드뉴스 무단전재 및 재배포 금지