i
Windows Embedded CE 6.0
CTSMExam 70-571
전매 금지.
인증 시험 준비준비 키트(Preparation Kit)
R2 콘텐츠로
업데이트
됨
ii
발행인
Microsoft Corporation
One Microsoft Way
Redmond, Washington 98052-6399
이 문서는 정보용입니다 . MICROSOFT 는 이 문서에 포함된 정보에 대해 ( 직접 , 간접 , 특별한 )그 어떤 보증도 하지 않습니다 . 이 문서에 포함된 정보는 발행일을 기준으로 토론된 문제점에 대한 Microsoft Corporation 의 현재 관점을 대표합니다 . Microsoft 는 변하는 시세에 대처해야 하기 때문에 정보에 대한 책임을 질 수 없으며 발행일 이후에 제공되는 정보의 정확성을 보장할 수 없습니다 . URL 과 기타 인터넷 웹사이트 참고 자료를 포함하여 이 문서에 있는 정보는 통보없이 변경될 수 있습니다 .
모든 적용되는 저작권 법을 준수하는 것은 사용자의 책임입니다 . 저작권 하에 권리 제한이 허용되지 않는 한 , Microsoft Corporation 의 명시적 서면 허가없이 이 문서의 그 어느 일부도 그 어떤목적으로든 무단으로 복제 , 검색 시스템으로 저장 또는 입력 , 또는 그 어떤 형태나 방식으로 전송( 전자 , 기계 , 복사 , 기록 , 또는 기타 ) 될 수 없습니다 . Microsoft 는 이 문서상에 언급된 주제에관련된 특허 , 특허 응용 프로그램 , 등록 상표 , 저작권 또는 기타 지적 재산권을 소유할 수 있습니다 . Microsoft 와의 서면 사용권 계약에 명시적으로 나타나 있지 않은 이상 , 이 문서의 제공으로인해 이러한 특허 , 등록 상표 , 저작권 및 기타 지적 재산권에 대한 그 어떤 사용권도 부여되지 않습니다 .
저작권 © 2008 Microsoft Corporation. 모든 권리 소유 .
Microsoft, ActiveSync, IntelliSense, Internet Explorer, MSDN, Visual Studio, Win32,Windows 및 Windows Mobile 은 Microsoft 회사 그룹의 등록 상표입니다 . 이 문서에 언급된 회사와 제품의 실제 이름은 해당 소유자의 상표일 수 있습니다 .
용례에 사용된 회사 , 기관 , 제품 , 도메인 이름 , 전자 메일 주소 , 로고 , 사람 , 장소 및 이벤트는 다른 설명이 없는 한 실제 데이터가 아닙니다 . 어떠한 실제 회사 , 기관 , 제품 , 도메인 이름 , 전자 메일 주소 , 로고 , 사람 , 장소 또는 이벤트와도 연관시킬 의도가 없으며 그렇게 유추해서도 안 됩니다 .
인수 편집인 : 산드라 웨버 (Sondra Webber), Microsoft Corporation
저자 : 니콜라스 베슨 (Nicolas Besson), Adeneo Corporation레이 마르실라 (Ray Marcilla), Adeneo Corporation라제쉬 캐이드 (Rajesh Kakde), Adeneo Corporation
집필 감독 : 워런 루보 (Warren Lubow), Adeneo Corporation
기술 검수인 : 브리지트 후왕 (Brigette Huang), Microsoft Corporation
편집 제작 : Biblioso Corporation
본문 번호 X00-00000
iii
간단한 내용
서문 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xi
소개 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xiii
1 운영체제 디자인 설계 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
2 런타임 이미지 빌드와 배포 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
3 시스템 프로그래밍 실행 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
4 디버깅 및 시스템 테스트 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
5 보드 지윈 패키지의 사용자 지정 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
6 장치 드라이버 개발 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 237
용어 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
색인 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
저자에 대하여 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
81
제 3 장
시스템 프로그래밍 실행
시스템 성능은 사용자의 생산성에서 아주 중요하다 . 그것은 장치에 대한 사용자
인식에 직접적인 영향을 준다 . 사실 , 사용자들이 시스템의 성능과 사용자 인터
페이스의 외양과 느낌 (look and feel) 을 기초 ( 바탕 ) 으로 하는 장치의 유용성
(usefulness) 을 판단하는 것은 일반적이다 . 인터페이스를 너무 복잡하게 제공함
으로써 , 장치의 잠재적인 보안 위험 노출 또는 예상치 못한 사용자의 조작으로
사용자들에게 혼란을 초래할 수도 있다 . 부정확한 응용 프로그램 프로그래밍 인
터페이스 (API), 또는 다중스레드 환경에서 부정확한 응용 프로그램 아키텍처를
사용으로 인하여 , 성능에 중대한 영향을 미칠 수 있다 . 성능 최적화 및시스템 커
스터마이징은 펨웨어 공급자에게 중대한 도전을 제시한다 . 이 장에서는 대상장
치에 시스템 응답시간을 최적화 시키는 도구와 최상의 연습에 주안점을 두어 논
의하고자 한다 .
이 장에서의 학습 목표 :
■ 시스템 성능의 감시 및 최적화
■ 시스템 응용 프로그램을 구현
■ 스레드 프로그래밍 및 스레드 동기화 개체들
■ 드라이버 및 응용 프로그램에서 예외 처리 구현
■ 시스템 수준에서 전윈 관리 지윈
82 제 3장 시스템 프로그래밍 실행
시작하기 전에이 장의 학습을 완벽하게 이해하려면 , 다음 과정을 수행하여야 한다 :
■ 인터럽트 , 타이머 그리고 운영 체제내 스케쥴러 기능과 같은 실시간 시스템
디자인 개념의 완전한 이해 .
■ 동기화 객체를 포함한 다중 스레드된 프로그래밍의 기본적인 지식 .
■ 마이크로소프트® 비주얼 스튜디오® 2005 서비스 팩 1 과 윈도우 임베디드
CE 6.0 에 통합된 플랫폼 빌더가 설치된 개발용 컴퓨터 .
제 1 과 : 시스템 성능의 감시와 최적화 83
제 1과 : 시스템 성능의 감시와 최적화성능 감시 및 최적화는 소형 - 풋프린트 장치 (small-footprint devices) 의 개발
에서 중요한 작업이다 . 직관적이고 리소스 집중적인 사용자 인터페이스에 대한
요건와 점점 복잡한 응용 프로그램의 증가 수로 인하여 최적화된 시스템 성능
의 요구는 중요한 요소로 남아 있다 . 펌웨어 설계자 및 소프트웨어 개발자는 자
신들의 제한된 시스템 구성요소와 응용 프로그램내에서 다른 구성 요소와 응용
프로그램들이 사용 가능한 리소스를 사용할 수 있도록 리소스 사용을 제한하도
록 요구받는다 . 장치 드라이버나 사용자 응용 프그램을 개발하는데 있어서 최적
의 프로세싱 알고리즘이프로세서 사이클을 줄이는데 도움이 되며 , 효율적인 테
이터 구조는 메모리를절약 할 수 있다 . 모든 시스템 수준에서 드라이버 , 응용프
로그램 , 그리고 다른 구성요소 사이의 성능 문제를 확인하는 도구가 존재한다 .
이 과정을 마치면 사용자는 다음을 할 수 있다 :
■ interrupt service routine (ISR) 의 대기시간 식별
■ 윈도우 임베디드 CE 시스템의 성능 개선 .
■ 시스템 성능 정보의 기록과 분석 .
예상 학습 시간 : 30 분
실시간 성능드라이버 , 응용프로그램 , 그리고 OEM adaptation layer (OAL) 코드는 시스템
과실시간 성능에 영향을 미친다 . 윈도우 임베디드 CE 는 실시간 과 비 실시간 구
성에 사용될 수 있지만 , 비 실시간 구성 요소들과 응용 프로그램들을 사용하는
것은 실시간 운영 체제에서 시스템 성능을 저하시킨다는 점이 중요하다 . 예를 들
어 페이지 요청 (Demand Paging), 장치 입 / 출력 및 전윈 관리는 실시간 장치들
을 위해 설계된 것이 아니며 이러한 기능들은 신중히 사용해야 한다 .
페이지 요청한정된 램 용량을 가진 다중 프로세스 사이에서 페이지 요청은 메모리 공유를 용
이하게 한다 . 페이지 요청이 활성화 되었을 때 , 윈도우 임베디드 CE 는메모리
가 부족한 경우에 동작중인 프로세스들에서 메모리 페이지들을 제거하고 삭제한
다 . 메모리내에 모든 동작중인 (active) 프로세스들의 코드를 유지하기 위해 , 동
적 - 링크 라이브러리 (DLL) 또는 장치 드라이버 같은 특정 모듈이나 전체 운영
체제에 필요한페이지 요청을 해제 시켜야 한다 .
다음과 같은방법으로 페이지 요청을 해제 시킬 수 있다 :
84 제 3장 시스템 프로그래밍 실행
■ 운영체제 Config.bib 파일안의 CONFIG 섹션에 있는 ROMFLAGS 옵션을
설정 .
■ DLLs 이DLL을 메모리에 로드하는 LoadLibrary 함수 대신에 LoadDriver
함수의 사용 .
■ 장치 드라이버 드라이버의 레지스트리 엔트리 (registry entry) 인
“Flags” 에 DEVFLAGS_LOADLIBRARY 플래그을 추가한다 . 이 플래그
는 Device Manager 가 드라이버를 로드하기 위해 LoadDriver 함수를 사용
하는 대신 LoadLibrary 함수를 사용하도록 하게 한다 .
윈도우 임베디드 CE 는 일상적으로 메모리를 할당시켜 사용한다 . 그러나 페이
지 요청을 해제하면 자동적으로 삭제되지 않는다 .
시스템 타이머시스템 타이머 는 밀리세컨드 (1/1,000 초 ) 당 한 틱 (tick) 의 주파수 에서 시스
템 틱을 생성하는 하드웨어 타이머이다 . 시스템 스케줄러는 시스템상에서 어느
시간에 어떤 스레드들이 실행되어야 하는지를 결정하는데 이 시스템 타이머를 사
용한다 . 프로세스내 스레드는 운영 체제에서 명령어들을 실행하기 위해 프로세
서 시간을 할당받은 최소 실행 가능한 단일체 (unit - 적어도 시간은 나타내는 단
위는 아니다 ) 이다 . 이 Sleep 함수를 사용하여 일정한 시간의 스레드를시킬 수
있다 . Sleep 함수를 전달할 수 있는 최소값은 1(Sleep(1)) 이다 . 다시 말하면 약
1 밀리세컨드의 스레드를 중지한다 . 그러나 그 Sleep 은 정확하게 1 밀리세컨드
는 아니다 . 왜냐하면 그 Sleep 시간은 현재 시스템 타이머의 틱에 그 이전의 시
스템 틱의 잉여 값을 더한 값을 포함하기 때문이다 . 그 Sleep 시간은 또한 스레
드의 우선순위에 관련이 있다그 스레드의 우선순위는 운영체제 프로세서에 실행
하는 스케줄의 순서에 따라 결정한다 . 그러한 이유로 실시간 응용프로그램에 대
한 정확한 타이머를 필요로 한다면 Sleep 함수를 사용해서는 안된다 . 실시간 목
적을 위한 인터럽트 또는 멀티미디어 타이머들 같은 전용 타이머를 사용한다 .
전윈관리전윈 관리 는 시스템 성능에 영향을 줄 수 있다 . 프로세스가 유휴 전윈 상태 (Idle
Power State) 로 들어갔을 때 , 주변 장치 혹은 시스템 스케쥴러에 의해 발생하
는 인터럽트는 이 유휴 상태를 빠져 나오게 하며 , 이전의 콘텍스트 (Context) 를
복윈하고 스케쥴러를 재기 ( 호출 ) 한다 . 전윈 콘텍스트 교환 (Power context
switching) 은 시간 - 소비 프로세스다 . 윈도우 임베디드 CE 의 전윈 관리 기능
에 대한 자세한 내용은 윈도우 Microsoft MSDN ® 웹사이트에서 http://msdn2.microsoft.com/en-us/library/aa923906.aspx. 의 윈도우 임베디드 CE
6.0 설명서에 있는 “전윈 관리” 섹션을 참고한다 .
제 1 과 : 시스템 성능의 감시와 최적화 85
시스템 메모리커널은 힙 (heaps: 힙 속성을 충족시키는 트리 - 기반 데이터 구조 ), 프로세스 ,
중요한 섹션 , 뮤텍스 , 이벤트 , 그리고 세마포어을 위하여 시스템 메모리를 할당
하고 관리한다 . 커널은 커널 객체를 해제 (releasing ) 할 때 시스템 메모리를 완
전히 프리 (free) 하지 않는 대신에 커널은그 다음의 할당을 위해서 재사용 하기
위한 시스템 메모리를 보유한다 . 할당된 메모리를 재사용하는 것이 좀 더 빠르기
때문에 , 커널은 부팅 프로세스 동안에 시스템 메모리 풀 (system memory pool)
을 초기화하고 이 풀 (pool) 네에 사용 가능한 메모리가 더 이상 없을 때에만 메모
리를 할당한다 . 시스템 성능은 프로세스들이 가상 메모리 , 힙 개체 그리고 스택
을 어떻게 사용하느냐에 따라 저하될 수 있다 .
비실시간 APIs시스템 APIs 나 , 그래픽 윈도우 이벤트 시스템 (GWES) APIs 를 호출하면서 윈
도우 드로잉 같은비 실시간 기능에 의존적인 일부 API 들을 유의해야 한다 . 비
실시간 포워딩 호출은 시스템 성능을 급격히 감소시킨다 . 따라서 실시간 응용
프로그램에 있는 APIs 가 실시간을 준수하는지 확인하여야 한다 . 파일 시스템 또
는 하드웨어를 접근 ( 억세스 ) 하기 위한 API 들은 리소스를 보호하기 위해 뮤텍
스 (mutex) 또는 크리티컬 섹션 (critical section) 과 같은 블로킹 메커니즘을 사
용하는 API 들 이므로 성능에 영향을 준다 .
참고 비 실시간 APIs
비 실시간 API 들은 실시간 성능상의 측정 가능한 영향력을 가지고 있다 . 불행하게도 , WIN32 ® API설명서는 실시간 문제의 세부사항에 대하여 간단한 정보만 제공한다 . 실제적인 경험과 성능 검사는사용자가 올바른 함수를 선택하도록 도울 수 있다 .
실시간 성능 측정 도구윈도우 임베디드 CE 는 시스템성능상에 Win32 API 들의 영향을 측정하기 위해
사용되어 질 수 있는 많은 성능 감시와 문제 해결 도구들을 포함한다 . 이러한 도
구들은 응용 프로그램이 시스템 메모리 할당을 해제하지 않는 비효율적인 메모
리 사용을 확인할 때 아주 유용하다 . 다음과 같은 윈도우 임베디드 CE 도구는
시스템 구성요소와 응용 프로그램이 실시간 성능을 측정하는 데 특히 유용하다 :
■ ILTiming Interrupt Service Routine (ISR) 과 Interrupt Service Thread
(IST) 의 대기 시간을 측정 .
■ OSBench 커널이 커널 객체들을 관리하는데 소요되는 시간을 추적함으로
써 시스템 성능을 측정 .
86 제 3장 시스템 프로그래밍 실행
■ 윈격 성능 모니터 (Remote Performance Monitor) 메모리의 사용량 , 네트
워크 처리량 그리고 다른 측면들을 포함한 시스템 성능을 측정 .
인터럽트 대기 시간 (ILTiming)ILTiming 도구는 ISR 과 IST 대기시간을 측정하고자 하는 Original Equipment
Manufacturers (OEMs) 에게 특별히 유용하다 . 구체적으로 ILTiming 은 인터럽
트가 발생한 후 ISR 이 실행되기 까지의 시간 (ISR Latency) 와 ISR 이 끝난 후 실
질적으로 IST 가 시작되기까지의 시간 (IST Latency) 을 측정할 수 있게 한다 .
이 도구는 기본적으로 시스템 하드웨어의 틱 타이머 (system hardware tick
timer) 를 사용하지만 이 타이머는 다른 타이머 ( 고성능 카운터 ) 로서도 사용이
가능하다 .
참고 하드웨어 타이머 제한사항
모든 하드웨어 플랫폼이 ILTIMING 도구에 대한 필수의 타이머 지윈을 제공하지 않는다 .
ILTiming 도구는 시스템 틱 인터럽트 관리를 위한 ISR 을구현하기 위해 OAL 에
서 OALTimerIntrHandler 함수에 의존한다 . 타이머 인터럽트 핸들러는 현재 시
간을 저장하고 ILTiming 응용 프로그램 스레드가 수신 대기중인 인터럽트 이벤
트 - SYSINTR_TIMING 을 리턴한다 . 이러한 스레드를 IST(Interrupt Service
Thread) 라 하며 , ISR 에서 인터럽트 수신에서 IST 에서의 SYSINTR_TIMING
이벤트의 수신까지의 경과 시간을 ILTiming 도구가 측정하는 IST 대기시간 (IST
latency) 이라 한다 . 윈도우 임베디드 CE 6.0 R2 에 통합된 마이크로소프트 플
랫폼 빌더를 설치하였다면 , 개발용 컴퓨터의 %_WINCEROOT%₩Public
₩Common₩Oak₩Utils 폴더에 있는 ILTiming 도구의 소스 코드를 볼 수 있다 .
ILTiming 도구는 사용자가 다음의 문법에 따라서 IST 의 우선순위와 유형을설정
하기 위해 사용할 수 있는 여러 개의 명령 - 라인 매개 변수를 지윈한다 :
iltiming [-i0] [-i1] [-i2] [-i3] [-i4] [-p priority] [-ni] [-t interval]
[-n interrupt] [-all] [-o file_name] [-h]
표 3-1 개별 ILTiming 명령 - 라인 매개변수에 대하여 좀 더 자세하게 설명한다 .
표 3-1 ILTiming 매개변수
명령 -라인 매개변수 설명
-i0 유휴 스레드가 없음 . 이것은 -ni 매개변수를 사용하는 것과 동일하다 .
-i1 어떠한 실제 프로세싱 수행 없이 동작하는 하나의 스레드
제 1 과 : 시스템 성능의 감시와 최적화 87
참고 유휴 스레드
ILTIMING 은 시스템의 활동을 생성하기 위해 유휴 스레드 명령 - 라인 매개변수 -I1, -I2, -I3, 그리고 -I4) 를 만들 수 있다 . 이는 IST 를 처리하기 전에 종료해야만 하는 비 선점형 커널 호출 (NON-PREEMPTIVE KERNEL CALL) 상태 (-) 로 두도록 하게 하며 , 백그라운드 태스크 (BACKGROUND TASK) 로서유휴 스레드를 활성화하는데 유용하다 .
운영체제 벤치마크 (OSBench)OSBench 도구는 커널이 커널 객체들을 관리하는 데소요한 시간을 식별함으로
써 , 시스템 성능을 측정하는데 도움이 될 수 있다 . 스케줄러를 기반으로 ,
-i2 SetThreadPriority(THREAD_PRIORITY_IDLE) 을 호출하고 , 동작하는 하나의 스레드 .
-i3 두 스레드가 10-second 시간종료로 SetEvent 와WaitForSingleObject 교체 .
-i4 10 초의 시간종료로 SetEvent 와 WaitForSingleObject를 상호 교차하는 하는 두 스레드 .
-i5 무한 시간 종료로 SetEvent 와 WaitForSingleObject 를 상호 교차하는 두 스레드
-p 우선순위 IST 우선순위 (0 through 255) 를 지정 . 기본 설정 값은 가장 높은 우선순위인 0 이다 .
-ni 유휴 상태 우선순위 스레드를 지정하지 않음 . 기본 설정값은 스레드가 유휴 상태 우선순위 스레드 스핀 값과 동일하다 . 이것은 -i0 매개변수와 동일한 값이다 .
-t interval 밀리세컨드에 있는 시간 틱으로, SYSINTR_TIMING 시간 간격을 지정한다 . 기본설정 값은 5 이다 .
-n 인터럽트 인터럽트의 수를 지정한다 . 이 매개변수를 이용하여 사용자는 얼마나 오랬동안 시험이 실행되는지 지정 할 수 있다. 기본설정 값은 10 이다 .
-all 모든 데이터를 출력하도록 지정 . 기본 설정 값은 단지 그 요약을 출력한다 . .
-o file_ 이름 출력을 파일로 지정 , 그 기본설정 값은 디버그 메시지 창의 출력으로 되어 있다 .
표 3-1 ILTiming 매개변수
명령 -라인 매개변수 설명
88 제 3장 시스템 프로그래밍 실행
OSBench 는 스케줄러 성능 - 타이밍 시험 방법으로 타이밍 측정을 수집한다 . 스
케줄러 성능 - 타이밍 시험은 스레드 동기화 같은 기본적인 커널 작업을 얼마나
많은 시간을 필요로 하는지 측정한다 .
OSBench는 사용자가 다음의 커널 동작에 대한 시간 정보 추적을 가능하게 한다:
■ 크리티컬 섹션 (Critical Section) 을 획득하거나 해제함 .
■ 이벤트를 대기하거나 신호를 보냄 .
■ 세마포어나 뮤텍스를 생성 .
■ 스레드를 내보내기 .
■ 시스템 API 를 호출 .
참고 OSBench 테스트
다른 시스템 구성에서 성능문제를 명확히 하기 위하여 , 마이크로소프 임베디드 CE 시험 키트 (CETK)같은 스트레스 시험도구와연계하여 OSBENCH 를 사용한다 .
OSBench 도구는 사용자가 커널동작에 대한 타이밍 표본을 수집하기 위하여 다
음 문법을 사용할 수 있는 여러 가지 명령 - 라인 매개변수를 지윈한다 .
osbench [-all] [-t test_case] [-list] [-v] [-n number] [-m address]
[-o file_name] [-h]
표 3-2 개개의 OSBench 명령 - 라인 매개변수에 대하여 상세하게 설명한다 .
표 3-2 OSBench 매개변수
Command line
매개변수
설명
-all 모든 시험을 실행 ( 기본설정 : -t option 에 의해 단지 지정된 것을 실행 ):
TestId 0: 크리티컬 섹션 (CriticalSections)
TestId 1: 이벤트설정 (set-wakeup)
TestId 2: 세마포우 해제 - 요구
TestId 3: 뮤텍스
TestId 4: 자발적 양보 (Voluntary yield)
TestId 5: PSL API 오버헤드 호출
TestId 6: Interlocked API( 감소 , 증가 , 테스트변환 , 변환 )
-t test_case TestID ( 각 시험을 위한 별도의 -t 가 필요함 )
제 1 과 : 시스템 성능의 감시와 최적화 89
시험 내용을 식별하기 위하여 OSBench 소스 코드를 확인한다 . 다음의 위치에서
소스 코드를 발견할 수 있다 :
■ %_WINCEROOT%₩Public₩Common₩Oak₩Utils₩Osbench
■ %_WINCEROOT%₩Public₩Common₩Oak₩Utils₩Ob_load
검사 결과는 기본설정을 디버그 출력으로 전송 받을 수 있으나 CSV file 바꿀 수
있다 .
참고 OSBench 요구사항
OSBENCH 도구는 시스템 타이머를 사용한다 . 그러므로 OAL 는 QUERYPERFORMANCECOUNTER 지윈해야 하고 , OEMINIT 함수에서 QUERYPERFORMANCEFREQUENCY 함수를초기화 해야한다 .
윈격 성능 모니터윈격 성능 모니터 (Remote Performance Monitor) 응용프로그램은 메모리 사용
량 , 네트워크 대기시간 , 그리고 다른 요소뿐만 아니라 운영체제의 실시간 성능
을 추적할 수 있다 . 각 시스템 요소는 사용법 (usage), 큐 길이 (queue length) 그
리고 지연 (delay) 상의 정보를 제공하는 일련의 지표 (indicator) 와 관련이 있다 .
윈격 성능 모니터는 대상장치에서 생성된 로그 파일을 분석 할 수 있다 .
윈격 성능 모니터 응용프로그램은 이름에 나타나듯이 윈격 도구를 뜻한다 . 개발
과 현장 양쪽 모두에 있는 응용프로 그램 모니터와 같이 , 사용자는 대상장치와
배포된 응용프로그램에 연결하는 통로를 가진다 .
윈격 성능 모니터는 다음의 객체들을 감시 한다 :
■ 윈격접근 서버 (RAS)
-list 설명된 시험 ID 목록
-v Verbose: 엑스트라 측정 세부 사항 보기
-n number 시험당 샘플의 수 ( 기본값 =100)
-m address Marker 값 작성을 위한 가상주소 ( 기본값 = <none>)
-o file_name comma-separated values (CSV) 파일 출력 ( 기본값 : 단지 디버그 하기 위한 출력 )
표 3-2 OSBench 매개변수
Command line
매개변수
설명
90 제 3장 시스템 프로그래밍 실행
■ 인터넷 제어 메시지 프로토콜 (ICMP)
■ 전송 제어 프로토콜 (TCP)
■ 인터넷 프로토콜 (IP)
■ 사용자 데이터 그램 프로토콜 (UDP)
■ 메모리
■ 배터리
■ 시스템
■ 프로세스
■ 스레드
이 리스트는 사용자 자신의 윈격 성능 모니터 확장 DLL 을 구현하는 것에 의해
확장된다 . 예제 코드로 % COMMONPROGRAMFILES%₩Microsoft
Shared₩Windows CE Tools₩Platman₩Sdk₩WCE600₩Samples₩CEPerf
폴더를 확인한다 .
윈도우 워크스테이션의 성능 도구와 유사하게 , 윈격 성능 모니터는 대상 장치에
서 가능한 성능 개체들을 기초로 성능 차트 생성 , 지정된 임계값에서 발생하는
경보를 구성 , 소스 로그 파일 작성 , 성능 리포트를 컴파일할 수 있다 . 표 3-1 은
성능 차트예제를 보여준다 .
표 3-1 윈격 성능 모니터의 성능 차트
제 1 과 : 시스템 성능의 감시와 최적화 91
하드웨어 검증ILTiming 도구 , OSBench, 그리고 윈격 성능 모니터는 대부분의 성능 감시 필요
성을 다룬다 . 그러나 일부의 경우 시스템 성능 정보를 수집하는 다른 방법이 요
구 될 수 있다 . 예를 들어 , 사용자가 정확한 인터럽트 대기 타이밍을 구하기 윈
하거나 , 하드웨어 플랫폼이 IL Timing 도구에 필요한 타이머 지윈을 제공하지
않는 경우 사용자는 GPIO(General Purpose Input/Output 인터페이스나 파형
생성기 (waveform generator) 에 의거한 하드웨어 기반 성능 측정 방법을 사용
해야만 한다 .
GPIO 의 파형 생성기를 사용하여 , ISR 와 IST 를 통해 다루어 지는 것은 인터럽
트를 발생하게 하는 것이 가능하다 . 그리고 나서 이 ISR 와 IST 는 수신된 인터
럽트에 응답하여 파형을 생성하여 위하여 다른 GPIO 을 사용한다 . 그리고 두 파
형 사이의측정된 시간 - 생성기로부터의 입력파형과 ISR 또는 IST 로부터 출력
파형 - 이 인터럽트의 대기시간이다 .
요점정리윈도우 임베디드 CE 는 시스템 성능을 측정하거나 실시간 장치 성능을확인하기
위해 개발 환경에서 사용되고 있는 다양한 도구를 제공한다 . ILTiming 도구는
인터럽트 대기시간을 측정하는데 유용하다 . OSBench 도구는 사용자가 어떻게
커널이 시스템 객체를 관리하는지 분석할 수 있게 한다 . 윈격 성능 모니터는 개
발 현장에 있는 장치의 보고서뿐만 아니라 차트 , 로그로 성능과 통계 자료를 수
집하는 방법을 제공한다 . 윈격 성능 모니터는구성 가능한 성능 임계 값에 기반하
여 경고를 생성시키는 능력을 가지고 있다 . 이러한 도구들의 능력을 넘어서 , 삭
제 및 변경 요청 대기시간과 성능 측정 목적을 위하여 하드웨어 감시를 사용할 수
있는 그 선택항목을 가지고 있다 .
92 제 3장 시스템 프로그래밍 실행
제 2 과 : 시스템 응용 프로그램의 구현제 1 장 " 운영 체제 설계의커스터마이징 하기 " 에서 논의된 것처럼 , 윈도우 임
베디드 CE 는 다양한 종류의 소형 풋 - 프린트 장치를 위한 구성요소화된 운영체
제 및 개발 플랫폼으로 역할을 한다 . 이러한 범위는 미션 크리터컬 (mission-
critical) 한 산업용 컨트롤와 같은 전용 작업을 위한 제한된 접근을 가진 장치에
서부터 개인 휴대용 단말기 (PDA) 와 같은 모든 설정돠 응용 프로그램으로 포함
하는 완전한 운영 체제에 대한 접근을 제공하는 개방형 플랫폼까지 다양하다 . 그
러나 , 실질적으로 모든 윈도우 임베디드 CE 장치들은 사용자에게 인터페이스를
제공하기하기 위한 시스템 응용 프로그램을 요구한다 .
이 과정을 마치면 사용자는 다음을 할 수 있다 :
■ Startup 시 응용 프로그램의 시작 .
■ 기본 쉘 변경 .
■ 쉘 커스터마이징 .
예상학습시간 : 25 분
시스템 응용프로그램 개요 .개발자들은 시스템 응용 프로그램과 사용자 응용 프로그램의 서로 다른 목적을
가지고 있음을 나타내기 위해 이들을 구분한다 . 윈도우 임베디드 CE 장치의 환
경에 있어서 , 일반적으로 시스템 응용 프로그램 (system application) 용어는 사
용자와 시스템간의 인터페이스를 제공하는 응용프로그램임을 나타낸다 . 대조적
으로 사용자 응용 프로그램 (user application) 은 사용자와 응용프로그램 - 특정
논리 및 데이터 사이에 인터페이스를 제공하는 프로그램이다 . 사용자 응용 프로
그램과 마찬가지로 , 시스템 응용 프로그램은 그래픽 또는 커맨드 라인 인터페이
스를 구현할 수 있지만 , 전형적으로 운영 체제의 일부로서 자동 실행된다 .
시작시 응용 프로그램 시작윈도우 임베디드 CE 초기화 과정의 일부로서 응용 프로그램들을 자동 시작되도
록 구성할 수 있다 . 이 기능은 윈도우 임베디드 CE 가 쉘 (shell) 사용자 인터페
이스 (UI) 를 로드 하기 전후에 응용프로그램이 실행하는 것을 윈하는지 여부에
따라 , 여러 방법으로 설정할 수 있다 . 한가지 방법은 응용 프로그램이 시작 동작
을 제어하는 여러 레지스트리 설정으로 조작할 수 있다 . 다른 일반적 방법으로는
표준 쉘 이 응용프로그램을 시작할 수 있도록 시작 폴더 안에 그 응용프로그램의
바로가기를 두는 것이다 .
제 2 과 : 시스템 응용 프로그램의 구현 93
HKEY_LOCAL_MACHINE₩INIT 레지스트리 키시작 시 와 Graphical Windows Event System (GWES) 같은 운영체제 구성요
소와 응용프로그램을시작하기 위해 , 윈도우 임베디드 CE 레지스트리는 여러 가
지 레지스트리 항목을 포함하고 있다 . 이러한 레지스트리 항목들은 표 3-2 와 같
이 HKEY_LOCAL_MACHINE₩INIT 레지스트리 키 아래 위치한다 . 표 3-2 와
같이 대상 장치상에 이러한 응용 프로그램들을 수작업으로 로드하고 실행할 필
요없이 런 - 타임 이미지내에 포함된 응용 프로그램를 실행하기 위해 이 위치에
추가적인 항목을 만들 수 있다 . 다른 것들 중에는 , 자동으로 시작하는 응용프로
그램을 소프트웨어 개발 동안 디버깅 활동을 용이하게 할 수도 있다 .
표 3-2 The HKEY_LOCAL_MACHINE₩INIT 레지스트리 키
표 3-3 은 전형적인 윈도우 임베디드 CE 구성요소가 런타임 이미지를 시작할 때 ,
시작되도록 레지스트리 항목의 세가지 보기를 열거한다 .
표 3-3 Startup 레지스트리 매개변수 보기
위치 HKEY_LOCAL_MACHINE₩INIT
구성요소 장치관리자 GWES Explorer
바이너리 Launch20="Device.dll"
Launch30="Gwes.dll"
Launch50="Explorer.exe"
종속변수 Depend20=hex:0a,00
Depend30=hex:14,00
Depend50=hex:14,00, 1e,00
설명 LaunchXX 레지스트리 항목은 그 응용프로그램의바이너리 파일을 지정하며 , DependXX 레지스트리 항목은 응용프로그램 간의 종속성을 정의한다 .
94 제 3장 시스템 프로그래밍 실행
표 3-3 의 Launch50 레지스트리 항목을 본다면 , 윈도우 임베디드 CE 의
Explorer.exe 는 프로세스 0x14(20) <Device Manager> 와 프로세스
0x1E(30)<GWES> 가 성공적으로 시작될 때 까지 실행되지 않을 것이다 .
DependXX 항목 에 있는 16 진수 값은 LaunchXX 항목의 이름으로지정된 10 진
launch 번호 XX 를 가르킨다 .
SignalStarted API 는 커널이 HKEY_LOCAL_MACHINE₩INIT 레지스트리 키
아래에 등록된 모든 응용 프로그램간의 프로세스 종속성을관리하도록 돕는다 .
응용 프로그램은 응용 프로그램이 시작되었고 초기화가 완료되었음을 커널에게
알리기 위해 SignalStarted 함수를 사용한다 . 아래의 코드 일부와 같이 ,
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
// Perform initialization here...
// Initialization complete,
// call SignalStarted...
SignalStarted(_wtol(lpCmdLine));
// Perform application work and eventually exit.
return 0;
}
종속성 처리는 간단하다 . 커널은 Launch 레지스트리 항목으로부터 런치 번호
(launch number) 를 결정하고 , 이를 순차 식별자로서 사용하며 WinMain 진입점
(entry point) 로 lpCmdLine 에 시작 매개변수로서 전달한다 . 응용 프로그램은
필요한초기화 작업을 수행하고 SignalStarted 함수의 호출로 이 부분이 완료된
사실을 커널에 통보한다 . SignalStated 함수는 DWORD 파라미터를 예상하고 있
기 때문에 SignalStated 코드 라인에 있는 _wtol 함수 호출은 문자열 런치 번호
(launch number) 를 long integer 값으로 변환 작업을 수행한다 . 예를 들어 , 커
널이 Explorer.exe 를 시작하기 위해서 장치 관리자는 SignalStarted 값 20 을
GWES 는 값 30 을 다시 커널에게 전달해야만 한다 .
Startup 폴더대상장치에 표준 쉘을 사용하는 경우 , 응용 프로그램이나 응용 프로그램의 바로
가기를 장치의 Windows₩Startup 폴더에 둘 수 있다 . Explorer.exe 는 이 폴더
를 검사하고 , 발견된 응용 프로그램을 시작한다 .
제 2 과 : 시스템 응용 프로그램의 구현 95
참고 사항 StartupProcessFolder 함수
대상 장치가 윈도우 임베디드 CE 표준 쉘을 실행하는 경우에 한하여 , WINDOWS₩STARTUP 폴더를 사용한다 . 표준 쉘을 사용하지 않고 동일한 목적으로 사용자 지정 시작 응용 프로그램 (CUSTOM LAUNCHAPPLICATION) 을 제작하는 경우 , HKEY_LOCAL_MACHINE_₩INIT 레지스트리 키 아래의 항목으로 기반으로시스템 시작시 그 응용 프로그램을 시작한다 . 시작 폴더와 응용 프로그램 실행을 검사하는 방법을보여주는 샘플 코드를 위하여 , %_WINCEROOT%₩PUBLIC₩SHELL₩OAK₩HPC₩EXPLORER₩MAIN 폴더에서EXPLORER.CPP 파일을 찾는다 . STARTUPPROCESSFOLDER 라 하는 함수를 찾고 구현을 위한 시작점으로서사용한다 .
윈도우 임베디드 CE 표준 쉘은 실행 및 바로 가기 파일을 처리할 수 있다 . 윈도
우 임베디드 CE 바로 가기 파일은 윈도우 XP 의 바로 가기 파일과는 다를 수 있
으나 , 유사한 기능을 제공한다 . CE 바로가기파일들은 .lnk 파일 확장자를 가진
텍스트 파일들 이다 . 그들은 다음의 문법을 따라서 그 링크한 대상을 위해 명령
- 라인 매개변수를 포함한다 .
nn# command [optional parameters]
In ternet Explorer 를 실행하고 홈페이지를 열기 위해
27#₩Windows₩iexplore.exe -home 처럼 nn 은 파운드 기호 (#) 이후의 실제
명령의 문자 개수를 나타낸다 . 런타임 이미지에 윈하는 .lnk 파일을 만들고 추가
한 후 , .lnk 파일을 시작 폴더에 매핑하기 위해 Platform.dat 또는 project.dat 파
일을 편집한다 . 다음의 .dat 파일 항목 처럼 추가한다 :
Directory("\Windows\Startup"):-File("Home Page.lnk", "\Windows\homepage.lnk")
2 장에서 이러한 구성 작업에 대해 좀 더 자세하게 다룬다 .
참고 시작 폴더 제한
시작 폴더의 핵심적인 장점은 START 폴더에 있는 응용 프로그램들이 초기화 및 시작 과정이 성공적으로 완료되었음을 커널에게 알리기 위해 SIGNALSTARTED API 를 구현할 필요가 없다는 것이 STARTUP 폴더의 핵심적인 장점이다 . 그렇지만 이는 운영 체제가 응용 프로그램간의 종속성을 관리 할 수 없고특정 시작 순서를 지정할 수 없다는 것을 의미한다 . 운영체제는 동시에 시작 폴더있는 모든 응용 프로그램들을 시작한다 .
시작 지연응용 프로그램을 자동으로시작하게 하는 흥미로운 옵션은 서비스 호스트 프로세
스 (Services.exe) 를 활용하는 것이다 . 비록 윈도우 임베디드 CE 가모든 기능
을 갖춘 서비스 제어 관리자 (Service Control Manager: SCM) 를 포함하지 않
지만 , 기본 제공 서비스를 포함하며 응용프로그램을 시작하는 데 이용될 수 있
는 Svcstart 라 하는 샘플 서비스가 동반된다 .
96 제 3장 시스템 프로그래밍 실행
Svcstart 는 시작 과정이 완료된 이후에 즉시 사용할 수 없는 시스템 구성요소 및
서비스에 종속성을 가진 응용 프로그램에 특히 유용하다 . 예를 들어 네트워크 인
터페이스 카드 (network interface card) 가 동적 호스트 구성 프로토콜 (DHCP)
서버로부터 인터넷 프로토콜 (Internet Protocol:IP) 주소를 얻어오거나 파일 시
스템을 초기화하는 데는 몇 초정도 걸릴 수 있다 . 이러한 경우를 대응하기 위해
. Svcstart 서비스는 응용 프로그램이 시작하기 전에 대기시간을 지정하는 Delay
매개변수를 지윈한다 . %_WINCEROOT%₩Public₩Servers₩SDK₩Samples
₩Services₩Svcstart 폴더에서 SvcStart 샘플 코드를 확인해 볼 수 있다 . 이 샘
플 코드를 Svcstart.dll 로 컴파일하고 , 이 DLL 파일을 런타임 이미지에 추가하
고 나서 sysgen -p servers svcstart 명령을 실행하여 운영체제에 Svcstart 서
비스를 등록한다 . Services.exe 을 사용하여 Svcstart.dll 을 로드한다 .
표 3-4 는응용 프로그램이 시작하기 위해 Svcstart 서비스가 지윈하는 레지스트
리 설정 목록이다 .
윈도우 임베디드 CE 쉘기본적으로 플랫폼 빌더는 대상장치와사용자간의 인터페이스 구현하기 위하여
세 가지 쉘 : 커맨드라인 쉘 , 표준 쉘 , 그리고 씬 클라이언트 쉘을 제공한다 . 각
쉘은 대상 장치와 상호 작용하는서로 다른 기능을 지윈한다 .
커맨드 라인명령 처리자 쉘은 콘솔 입력과 출력에게 제한된 명령어 세트를 제공한다 . 이 쉘
은디스플레이 가능한 장치 및 키보드나 디스플레이 스크린이 없는디스플레이 가
능한 헤드리스 (UI 가 없는 ) 장치에 모두 사용할 수 있다 . 디스플레이 가능한 장
치를 위하여 , 명령 프로세스 쉘은 명령 - 프롬프트 창을 통하여 입출력을처리할
수 있도록 콘솔 윈도우 컴포넌트 (Cmd.exe) 를 포함한다 . 이와는 반대로
Headless 장치는 입출력을 위하여 시리얼 포트를 일반적으로 사용한다 .
표 3-4 Svcstart 레지스트리 매개변수
장소 HKEY_LOCAL_MACHINE₩Software₩Microsoft₩Svcstart₩1
응용 프로그램 경로 @="iexplore.exe"
명령 - 라인 매개변수 Args="-home"
지연 시간 Delay=dword:4000
설명 ms 단위로 정의된 지연시간 이후에 지정된 명령 - 라인 매개변수로 응용 프로그램을 시작한다 . 자세한 내용은 Svcstart.cpp 파일을 참조한다 .
제 2 과 : 시스템 응용 프로그램의 구현 97
표 3-5 는 명령 프로세스 쉘과 함께 대상 장치에서 시리얼 포트를 사용하기 위해
구성해야할 레지스트리 설정 목록이다 .
윈도우 임베디드 CE 표준 쉘표준 쉘은 윈도우 XP 바탕화면과 비슷한 그래픽 사용자 인터페이스 (GUI) 를 제
공한다 . 표준 쉘의 기본적 목적은대상 장치에서 사용자 응용 프로그램들을 시작
하고 실행하는 것이다 . 이 쉘은 사용자가 응용 프로그램간 전환을 가능케 하는 작
업 표시줄과 시작 메뉴가 있는 바탕 화면을 포함한다 . 또한 표준 쉘은 네트워크
인터페이스들의 상태와 현재 시스템 시간과 같은 추가적인 정보를 표시하는 시
스템 알림 영역 (system notification area) 를 포함한다 .
만일 비주얼 스튜디오의 OS Design Wizard 를 사용하여 OS design project 를
생성할 때엔터프라이즈 터미널 디자인 템플릿 (Enterprise Terminal design
template) 을 선택 한다면 윈도우 임베디드 CE 표준 쉘 . 은 필수의 카탈로그 아
이템이다 . 만일 이 쉘을 복제하거나 사용자 지정을 윈한다면 %_WINCEROOT
₩Public₩Shell₩OAK₩HPC 폴더에 있는 소스 코드를 발견할 수 있다 . 1 장은
카탈로그 항목을 복제하고운영체제 디자인에 추가하는 방법을 설명한다 .
씬 클라이언트 쉘
제품설명서에서 윈도우 - 기반터미널 (Windows-based Terminal: WBT) 쉘로
호칭되는 씬 클라이언트 쉘은지역적으로 사용자응용 프로그램들이 실행되지 않
는 씬 클라이언트 장치를 위한 GUI 쉘이다 . 인터넷 익스플로러를 씬 클라이언트
표 3-5 콘솔 레지스트리 매개변수
장소 HKEY_LOCAL_MACHINE₩Drivers₩Console
레지스트리 항목 OutputTo COMSpeed
형태 REG_DWORD REG_DWORD
기본값 None 19600
설명 명령 프로세스 쉘이 입출력을 위하여 사용하는 시리얼 포트 정의 .
■ 이 값을 -1로 설정하여입출력을 디버그 포트로 경로 변경한다 .
■ 값을 0 으로 설정 지정하면경로 변경은 없다 .
■ 값을 0 보다 크거나 10 보다 미만으로 설정 지정하면입출력을 시리얼포트로 경로 변경한다 .
시리얼 포트의 데이터 전송 속도를 초당 비트 (bps) 로지정 .
98 제 3장 시스템 프로그래밍 실행
운영 체제 설계에 추가할 수 있다 . 그러나 이 경우 다른 사용자 응용프로그램들
이 네트워크의 터미널 서버에서 실행해야 한다 . 씬 클라이언트 쉘은 그 터미널
서버에 연결되고 윈격 윈도우 바탕화면을 화면 표시하기 위하여 윈격 바탕화면
프로토콜 (Remote Desktop Protocol: RDP) 을 사용한다 . 기본적으로 씬 클라
이언트 쉘은 윈격 바탕화면은 전체 화면 모드로 표시한다 .
Taskman
개발자는 윈도우 작업 관리자 (TaskMan) 쉘 응용 프로그램을복제하고 사용자
지정으로 자신의 쉘을 구현할 수 있다 . %_WINCEROOT%₩Publ ic
₩Wceshellfe₩Oak₩Taskman 폴더에 있는 소스 코드는 좋은 출발점 . 이다 .
윈도우 임베디드 CE 제어판제어판은 시스템과 응용 프로그램 구성 도구에 중앙 접근을 위한 특별한 저장소
(repository) 이다 . 제품 문서화는 이러한 구성 도구들이 제어판에 포함되었음을
보여주기 위해 애플릿 (applet) 처럼 구성 도구들을 참조한다 . 각각의 애플릿은
상세하고 특정한 목적을 제공하고 다른 애플릿에 의존하지 않는다 . 자신의 애플
릿을 추가하거나 또는 윈도우 임베디드 CE 에 포함된 제어판 애플릿을 제거함으
로써 제어판 내용을 사용자 지정할 수 있다 .
제어판 구성요소들제어판은 다음의 세가지 주요 구성 요소에 의존하는 configuration system 이다 :
■ Front-End (Control.exe) 이 응용 프로그램은사용자 인터페이스를 화면
에 표시하고 제어판 애플릿의 시작을 용이하게 한다 .
■ Host Application (Ctlpnl.exe) 이 응용 프로그램은 제어판 애플릿들을 로
드하고 실행한다 .
■ 애플릿 애플릿은 제어판 사용자 인터페이스에서 아이콘과 이름으로 나열
되며 .cpl 형태로 구현된 개개의 구성 도구이다 .
윈도우 임베디드 CE 제어판의 상세한구현은 , %_WINCEROOT%₩Public₩
₩Oak₩Ctlpnl 폴더의 소스코드를검토 한다 . 제어판 코드를 복제할 수 있고 자
신만의 제어판버전으로 구현함으로써 사용자 지정으로 할 수 있다 .
컨트롤 패널앞에서 언급한 바와 같이 , 제어판 애플릿은 시스템 구성요소 또는 사용자 응용
프로그램을 위해 대상 장치의 윈도우 폴더 (₩Windows) 에 .cpl 파일 형태로 구
현된 구성 도구이다 . 본질적으로 , .cpl 파일은 CPlApplet API 를 구현한 DLL 이
다 . 하나의 .cpl 파일은 여러 제어판 응용 프로그램들을 포함할 수 있지만 , 하나
제 2 과 : 시스템 응용 프로그램의 구현 99
의 애플릿은 여러 .cpl 파일들을 묶을 수 없다 . 모든 .cpl 파일들은 CPlApplet API
를 구현하기 때문에 , Control.exe 가 그 사용자 인터페이스에 사용가능한 애플
릿들을 화면표시하기 위해서시작시 구현된 애플릿들에 대한 상세한 정보를 얻는
것은 간단한 프로세스다 . Control.exe 는 단지 윈도우 폴더에 모든 .cpl 파일을
열거하고 각 파일의 CPlApplet 함수를 호출할 필요가 있다 .
DLL 속성과 CPlApplet API 요구 ( 조건 ) 에 의하면 , .cpl 파일은 다음의일반적
인 (public) 두 진입점 (entry point) 들을 구현해야 한다 :
■ BOOL APIENTRY DllMain(HANDLE hModule, DWORD
ul_reason_for_call, LPVOID lpReserved) DLL 을 초기화하 하는 데 사
용된다 . 시스템은 DLL 을 로드하기 위하여 DllMain 을 호출한다 . DLL 은
초기화가 성공되면 참 (true) 를 리턴하고 , 실패하면 거짓을 리턴한다 .
■ LONG CALLBACK CPlApplet (HWND hwndCPL, UINT message,
LPARAM lParam1, LPARAM lParam2) 콜백함수 (Callback Function) 는
애플의 동작들을 수행하기 위해 제어판에 대한 진입점으로서의 역할을 한다 .
참고 DLL 진입점
DLLMAIN 과 CPLAPPLET 진입점들은 제어판 응용 프로그램들이 이 진입점들을 액세스 ( 접근 ) 할 수 있도록 엑스포트 (노출 )되어야 한다 . EXPORT 되지 않은 함수들은 DLL에 있어서 PRIVATE 속성을 가진다 .C 인터페이스를 EXPORT 하기 위해서 함수의 정의들은 EXPORT “C” {} 블록내에 있어야 한다 .
제어판은 애플릿을 초기화하고 , 정보을 얻고 , 사용자 동작들에 대한 정보를 제
공하고 , 애플릿을 언로드 하기 위해 CplApplet 함수를 호출한다 . 애플릿은 모든
기능들이 가능한 CplApplet 인터페이스를 구현하기 위해 표 3-6 에 나열된 것 같
이 여러 제어판 메시지들을 제공해야 한다 :
Table 3-6 제어판 메시지
제어판 메시지 설명
CPL_INIT 제어판은 애플릿의 글로벌 초기화를 수행하기 위하여 이 메시지를 전송한다 . 메모리 초기화는 이 단계에서되는 전형적인 작업이다 .
CPL_GETCOUNT 제어판은 .cpl 파일에 구현된 제어판 응용 프로그램의 개수를 결정하기 위해 이 메시지를 보낸다 .
100 제 3장 시스템 프로그래밍 실행
참고 NEWCPLINFO 정보
제어판 애플릿에 구현된 각 제어판 응용 프로그램에 대한 NEWCPLINFO 정보는 .CPL 파일의 내장된 리소스에 저장된다 . 이것은 아이콘 , 이름 , 그리고 CPL_NEWINQUIRE 메시지에 대한 응답으로 리턴된 애플릿 설명을 현지화시키는 것을 용이하게 한다 .
컨트롤 패널 생성
제어판 애플릿을 빌드하고관련된 .cpl 파일을 생성시키기 위해 , 애플릿
subproject 의 소스 코드 폴더를찾고 Sources 파일의 끝에 새로운 라인으로 아래
의 CPL 빌드 지시문을 추가한다 :
CPL=1
또한 도표 3-3 그림과 같이 , 비주얼 스튜디오의 애플릿 subproject 설정에서 C/
C++ 탭에 있는 Include Directories 항목에 제어판 헤더 파일의 경로를 추가해
야 한다 .
$(_PROJECTROOT)₩CESysgen₩Oak₩Inc
CPL_NEWINQUIRE 제어판은 CPL_GETCOUNT 에 의해 명시된 제어판 응용 프로그램들에게 이 메시지를 보낸다 . 이 메시지를보낸다 . 이단계에서각각의 제어판 응용 프로그램은 제어판 사용자 인터페이스에 화면표시하기 위해 그 아이콘과 제목을 명시하여 NEWCPLINFO 구조체를 리턴해야한다 .
CPL_DBLCLK 사용자가 제어판 사용자 인터페이스 안에 있는 애플릿 아이콘 더블 클릭할 때 제어판은 이 메시지를 전송한다 .
CPL_STOP 제어판은 CPL_GETCOUNT에 지정된 각 인스턴스에 한번 이 메시지를 전송한다 .
CPL_EXIT 제어판은시스템이 DLL 을 릴리스하기 전에 한번 애플릿에 이 메시지를 보낸다 .
Table 3-6 제어판 메시지
제어판 메시지 설명
제 2 과 : 시스템 응용 프로그램의 구현 101
그림 3-3 제어판 애플릿을 위한 Include Directories 항목
Kiosk 모드 활성화 메디컬 모니터링 장치 , 현금 자동 인출기 (ATM) , 또는 산업용 제어 시스템 같은
많은 윈도우 임베디드 CE 장치는 하나의 작업에만 전담한다 . 표준 그래픽 쉘은
이 장치에 대해서 유용하지 못하다 . 그 표준 쉘을 제거하는 것은 제어판 구성 설
정으로의 접근을제한 할 뿐만 아니라 추가적인 응용 프로그램들이 시작되는 것
으로부터 사용자들을 보호한다 . 이처럼 직접적으로 어떤 쉘 접근도없고대상 장
치의 특별한 목적에 따른 응용 프로그램을 여는 것은 키오스크 모드에 있는 장치
이다 .
윈도우 임베디드 CE 를 위한 Kiosk 응용 프로그램은 native 코드나 managed
코드로 개발된다 . 유일한 필요사항은 그 표준 쉘 (Explorer.exe) 대신 이 응용
프로그램을시작하는 것이다 . 그리고 나서 , 그 시스템은 블랙 쉘을 시작한다 . 다
시 말해 , 블랙 쉘이란 어떤 장치에 실행되는 쉘 응용 프로그램이 없는 것을 말한
다 . 이러한 구성을 구현하기 위해서는 HKEY_LOCAL_MACHINE₩Init 키 아래
레지스트리 항목들을 구성할 필요가 있다 . 이 장에서 앞서 언급된 바와 같이 ,
Explorer.exe 를 위한 LaunchXX 항목은 Launch50 이다 . 표 3-7 에 나타나는
것과 같이 , 사용자지정 키오스크 응용 프로그램으로 Explorer.exe 를 교체하고
완료된 작업을 고려한다 . 사용자지정 키오스크 응용 프로그램은커널이 응용 프
로그램 종속성들을 올바르게 관리할 수 있도록 SignalStarted API 를 구현해야
한다 .
102 제 3장 시스템 프로그래밍 실행
참고 Managed 응용 프로그램을 위한 키오스크 모드
표준 쉘 대신에 관리된 응용 프로그램을 실행시키기 위해 , 런타임 이미지에 바이너리 파일을 포함하고 관리된 응용 프로그램에 속하는 .BIB 파일을 편집한다 . 특히 시스템이공통 언어 런타임 (COMMONLANGUAGE RUNTIME: CLR) 내에서 응용 프로그램을 로드하기 위해서 FILES 섹션에 바이너리 파일을 정의해야 한다 .
요점정리윈도우 임베디드 CE 는 광범위한 항목과 사용자 지정화된 특징을 가진 구성요소
화된 운영체제이다 . 그런 특징중의 하나는 시스템 시작시 응용프로그램들이 자
동으로 실행되도록 구성할 수 있게 한다 . 이는설치와 구성 도구에 대해서 특히 유
용하다 . 사용자 지정 .cpl 파일에서 구현된 , 사용자 자신의 애플릿을 추가함으로
써 제어판을 또한 사용자 지정 할 수 있다 . 그것은 제어판이 애플릿 안으로 호출
할 수 있도록 CPlApplet API 를 사용하는 DLL 이다 . 현금 자동 인출기 , 티켓 발
급기 , 메디컬 모니터링 시스템 , 공항 체크 - 인 단말기 , 또는 산업용 제어 시스
템 같은 특수 - 목적 장치를 위하여 , 사용자는 사용자의 키오스크 응용 프로그램
으로 표준 쉘을 교체함으로써 사용자 환경을 더 많이 지정할 수 있다 . 사용자는
코드 베이스 또는 윈도우 임베디드 CE 운영체제의 시작 과정을 사용자 지정할 필
요는 없다 . 키오스크 모드를 가능하게 하는 것은 단지디폴트 Launch50 레지스
트리 항목을 표준 혹은 managed 코드 응용 프로그램을 가리키는 사용자 지정
Launch50 으로 대치하는 작업이다 .
표 3-7 Startup 레지스트리 매개변수 예제
장소 HKEY_LOCAL_MACHINE₩INIT
컴포넌트 사용자 지정 키오스크 응용 프로그램
바이너리 Launch50="myKioskApp.exe"
종속성 Depend50=hex:14,00, 1e,00
설명 키오스크 모드를 활성화 하기 위해서 ( 는 ), 장치 레지스트리내 Explorer.exe 에 대한 Launch50 항목을 사용자 정의 키오스크 응용 프로그램을 가리키는 항목으로 대치한다 .
제 3 과 : 스레드와 스레드 동기화 구현 103
제 3과 : 스레드와 스레드 동기화 구현윈도우 임베디드 CE 는 다중스레드 운영체제이다 . 프로세싱 모델은 프로세스들
이 복수의 스레드들을 포함할 수 있기 때문에 UNIX 를 기초로 하는 임베디드 운
영체제와 다른다 . 사용자는 대상 장치에서 다중 스레드 응용 프로그램들과 드라
이버들을 구현 및 디버그하고 , 최적의 시스템 성능을 달성하기 위해서 단일 스레
드내 , 프로세스들간의 ( 이러한 ) 스레드들을 어떻게 동기화 , 스케쥴 그리고 관
리하는지를 이해할 필요가 있다 .
이 과정을 마치면 사용자는 다음을 할 수 있다 :
■ 스레드의 생성과 중지 .
■ 스레드 우선순위 관리 .
■ 다중 스레드의 동기화 .
■ 스레드 동기화 문제의 디버그 .
예상 학습시간 : 45 분
프로세스와 스레드프로세스는 응용 프로그램의단일 인스턴스이다 . 프로세스는프로세스는 가상 주
소 공간 , 실행 가능한 코드 , 시스템 개체들에 대한 핸들들을 여는 것 , 보안 내역
(security context), 유일한 프로세스 식별자 그리고 환경 변수들을 포함할 수 있
는 프로세싱 콘텍스트를 가지고 있다 . 또한 주요한 실행 스레드를 가진다 . 스레
드는 스케줄러에 의해 관리된 실행의 기본 단위이다 . 윈도우 프로세스에서 , 스
레드는 추가적인 스레드들을 만들 수 있다 . 프로세스 당 스레드들의 어떤 하드
코딩된 (hard-coded) 최대값은 있지 않다 . 모든 스레드는 메모리를 사용하고 물
리 메모리는그플랫폼에 제한되기 때문에 최대 수는 사용가능한 메모리 리소스에
의존한다 . 사용할 수 있는 메모리 리소스에 따라 그 최대값은 달라진다 . 왜냐하
면 모든 스레드는 사용하는 메모리와 플랫폼의 실제 메모리에 따라 제한된다 . 윈
도우 임베디드 CE 에서 프로세스의 최대개 수는 32,000 개로 제한된다 .
윈도우 임베디드 CE 에서 스레드 스케줄링윈도우 임베디드 CE 는 다양한 프로세스로부터 다중의 스레드를 동시에 수행하
기 위해 선점형 멀티태스킹을 지윈한다 . 윈도우 임베디드 CE 는 우선순위에 기
반하여 스레드 스케쥴링을 수행한다 . 시스템에 있는 각각의 스레드는 0 에서 255
까지 범위의 우선순위 가지고 있다 . 우선순위 0 은가장 높은 우선순위이다 . 스케
쥴러는 우선순위 리스트를 유지하고 그 스레드 우선순위에 따라서 라운드 - 로빈
(round-robin) 방식으로다음에 실행되어야 할 스레드를 선택한다 . 동일한 우선
104 제 3장 시스템 프로그래밍 실행
순위의스레드들은 임의의순서로 순차적으로 실행한다 . 스레드 스케쥴링은 시간
- 분할 (time-slice) 알고리즘에 의존한다는 점이 중요하다 . 각각의 스레드는 단
지 한정된시간 동안에만 실행될 수 있다 . 스레드가 실행할 수 있는최대 가능한
시간 분할을 퀀텀 (quantum) 이라 한다 . 일단퀀텀의시간 경과한 후 . 스케쥴러는
그 스레드를 중지시키고 리스트에 있는다음의 스레드를 재시작한다 .
응용 프로그램들은 응용 프로그램의 요구에 따른 스레드 스케쥴링을 변형하기 위
해 thread-by-thread 방식으로 퀀텀을 설정 할 수 있다 . 그렇지만 스케쥴이 먼
저 실행하기 위해 높은 우선순위의 스레드들을 선택하기 때문에 스레드에 대한
퀀텀의 변경은 높은 우선순위의 스레드에 영향을 주지 않는다 . 심지어 , 높은 우
선순위 스레드가 실행 사용가능하게 된다면 , 스케쥴러는 그들의 시간 - 분할내
에서 낮은 우선순위 스레드를 중지시킨다 .
프로세스 관리 API윈도우 임베디드 CE 는핵심 Win32 API 의 일부로 다수의 프로세스 관리 함수를
포함한다 . 세가지 중요한 함수는 프로세스를 새로 만들고 끝내는 데 유용한 표
3-8 에 나열된다 .
참고 프로세스 관리 API
프로세스 관리 함수와 완전한 API 문서화에 대한 더 많은 정보는 , WINDOWS MOBILE ® 6 와 WINDOWSEMBEDDE CE 6.0 의 CORE OS REFERENCE 에서 볼 수 있으며 MICROSOFT MSDN 웹사이트 http://msdn2.microsoft.com/en-us/library/aa910709.aspx. 에서도 확인이 가능하다 .
스레드 관리 API각각의 프로세스는 기본 스레드를 호출하는 적어도 하나의 스레드를 가지고 있
다 . 이것은 프로세스의 메인 스레드이다 . 이것은 메인 스레드를 종료하거나 빠
져나오는 것은 그 프로세스의 종료를 의미한다 .
표 3-8 프로세스 관리 함수
함수 설명
CreateProcess 새로운 프로세스 시작 .
ExitProcess 프로세스 정리와 함께 프로세스를 종료하고 DLL 들을 메모리에서 내림
TerminateProcess 프로세스 정리없이 프로세스를 끝내고 DLL 들을 메모리에서 내림
제 3 과 : 스레드와 스레드 동기화 구현 105
그 스레드는 또한 병렬 계산 수행 또는 다른 프로세스 작업 수행하는 , 작업자 스
레드 같은 , 추가적인 스레드들을 만들 수 있다 .
이 추가적인 스레드들은 필요하다면핵심 Win32 API 를 사용함으로써 더 많은 이
추가적인 스레드들은 새로 만들 수 있다 .
표 3-9 는 윈도우 임베디드 CE 에서 스레드들과 관련되고 응용 프로그램에서 사
용되는 가장 중요한 함수들의 리스트이다 .
추가정보 스레드 관리 API
스레드 관리 함수와 완전한 API 설명서에 대한 더 많은 정보를 위하여 , 윈도우 모바일 6 와 윈도우임베디드 CE 6.0 의 경우 http://msdn2.microsoft.com/en-us/library/aa910709.aspx 에서 MICROSOFTMSDN 웹사이트의 이용가능한 CORE OS REFERENCE 를 참조한다 .
스레드 생성 , 스레드 종결 , 스레드 종료새로운 스레드를 만드는 데 사용되는 CreateThread 함수는시스템이 스레드를
생성하는 방법을 제어하는 여러가지 매개변수와 스레드가 동작하도록 하는 명령
을 요구한다 . 이러한 매개변수들을 대부분 null 또는 0 로 설정하는 것이 가능할
표 3-9 스레드 관리 함수
함수 설명
CreateThread 새로운 스레드 생성하기 .
ExitThread 스레드 종료하기 .
TerminateThread 다른 코드나 정리를 수행하지 않고 지정된 스레드를 종결한다 . 스레드를 종결시키는 것은 메모리 개체들을 남겨두게 되고 이는 메모리 누수가 발생하기 때문에 극단적인 경우에만 이 함수를 사용한다 .
GetExitCodeThread 스레드 종료 코드를 리턴한다 .
CeSetThreadPriority 스레드 우선순위를 설정한다 .
CeGetThreadPriority 현재 스레드 우선순위를 얻는다 .
SuspendThread 스레드를 ( 일시 ) 정지한다 .
ResumeThread 일시 ) 정지된 스레드를 다시 시작한다 .
Sleep 지정된 시간 동안 스레드를 ( 일시 ) 정지한다 .
SleepTillTick 다음 시스템 틱까지 스레드를 일시정지한다 .
106 제 3장 시스템 프로그래밍 실행
지라도 , 적어도 응응 프로그램 즉 , 스레드가 실행될 이미 정의된 함수의 포인터
를 제공해야 한다 . 이 함수내에서 다른 함수들을 호출할 수 있을지라도 , 일반적
으로 이 함수는 스레드에 대한 핵심 프로세싱 명령 (core processing
instructions) 들을 정의한다 . 컴파일시 링커 (linker) 가 핵심 함수의 시작 주소
를 결정할 수 있어야 하기 때문에정적 참조 (static reference) CreateThread 에
게 그핵심 함수를 전달하는 것이 중요하다 . 비 정적 함수 포인터 (non-static
function pointer) 를 전달하면 동작하지 않는다 .. 다음의 코드 리스트는 사용자
가 %_WINCEROOT%₩Public₩Shell₩OAK ₩HPC₩Explorer₩Main 폴더에
서 볼 수 있는 Explorer.cpp 파일로부터 복사된다 . 이는 스레드 생성 방법을 보
여준다 .
void DoStartupTasks()
{
HANDLE hThread = NULL;
// Spin off the thread which registers and watches the font dirs
hThread = CreateThread(NULL, NULL, FontThread, NULL, 0, NULL);
if hThread)
{
CloseHandle(hThread);
}
// Launch all applications in the startup folder
ProcessStartupFolder();
}
이 코드는 새로운 스레드의 핵심 함수로서 FontThread 를 지정한다 . 현재의 스
레드는이 핵심 함수를 필요로 하지 않기 때문에 리턴된 스레드 핸들을 바로 닫는
다 . 이 새로운 스레드는 현재의 스레드와 함께 실행되고 묵시적으로 핵심 함수로
부터 리턴되자 마자 종료된다 . 이것은 C++ 함수가 정리를 할수 있게 하기 때문
에 스레드들을 종료하는데 선호하는 방법이다 . 명시적으로 ExitThread 를 호출
하는 것은 필요하지 않다 .
그러나 핵심 함수의 마지막 부분까지도 도달하지 않은 상태에서 프로세싱을 종
료하기 위해 스레트 루틴 (thread routine) 에서 ExitThread 함수를 명시적으로
호출하는 것도 가능하다 . ExitThread 는 현재의 스레드가 분리되고 있다는 것
을 나타내는 값으로 부착 ( 첨부 ) 되었던 모든 DLL 의 진입점을 호출하고나서 현
재의 스레드를 종결하기 위해 현재 스레드의 스택을 해제한다 . 현재의 스레드가
기본 스레드라면 그 응용 프로그램 프로세스는 종료된다 . ExitThread 가 그 현
재 스레드상에서 동작하기 때문에 , 스레드 핸들을 지정할 필요는 없다 . 그러나
사용자는숫자로 된 종료 코드 (exit code) 를 전달해야 한다 . 그래야 다른 스레드
들이 GetExitCodeThread 함수를 이용하여 그 코드값을 되받을 수 있다 . 이 과
정은 스레드 종료에 대한 이유와 에러를 식별하는 데 유용하다 . ExitThread 가
제 3 과 : 스레드와 스레드 동기화 구현 107
명백히 호출되지 않는다면 , 그 종료 코드는 그 스레드 함수의 리턴값과 일치한다 .
GetExitCodeThread 가 STILL_ACTIVE 값을 리턴한다면 , 그 스레드는 여전히
활성화된 상태가 되고 실행한다 .
사용자가 그것을 회피했을지라도 , TerminateThread 함수를 호출하는 것을 제
외한 스레드를 종결하기 위한 다른 어떤 방법도 없다는 것은 드문 상황이다 . 파
일 기록을 파괴하고 정상적으로 움직이지 않는 스레드는 이 함수를 요구할 지도
모른다 . 파일 시스템을 포맷하는 것은 사용자의 코드가 여전히 개발중인 동안 ,
디버깅 세션에 TerminateThread 를 호출하는 것을 사용자에게 요구 할 지도 모
른다 . 사용자는종료될 스레드와 종료 코드에 그 핸들을 전달할 필요가 있으며 그
것은 사용자가 GetExitCodeThread 함수를 사용하는 것에 의해 후에 찾아서 가
져올 수 있다 . TerminateThread 함수를 호출하는 것은 정상적인 일부 과정이어
서는 안된다 . 그 스레드 스택과 첨부된 DLL 남겨지거나 , 종료된 스레드에 포함
된 크리티컬 섹션과 뮤텍스가 버려지게 되면 , 메모리 누수나 불안정을 초래한다 .
프로세스 종료 절차의 부분으로 TerminateThread 를 사용하지 않는다 . 프로세
스 안에 있는 스레드들은 ExitThread 함수를 묵시적으로 또는 명백히 사용함으
로써 종료된다 .
스레드 우선순위 관리각 스레드는 시스템이 프로세스내 그리고 프로세스들간에 다른 모든 스레드들과
관련하여 실행될 스레드를 어떻게 관리하는 지를 결정짓는 0 에서 255 사이의 우
선순위 값을 가지고 있다 . 윈도우 임베디드 CE 에서 , 핵심 Win32 API 는 다음
과 같이 스레드의 우선순위를설정하는 4 개의 스레드 관리 함수들을 포함한다 .
■ 기본 우선순위 수준 윈도우 임베디드CE의이전 버전과 호환되는 수준(0-7)
에서스레드 우선순위를 관리하기 위해 SetThreadPr ior i ty 및
GetThreadPriority 함수를 사용한다 .
■ 모든 우선순위 수준 모든 수준 (0-255) 에서 스레드 우선순위를 관리하기 위
해 CeSetThreadPriority 및 CeGetThreadPriority 함수를 사용한다 .
참고 기본 우선순위 수준
윈도우 임베디드CE 이전 버전의 0에서 7까지 기본 우선순위는 지금 CESETTHREADPRIORITY의함수 248에서 255 까지 8 가지 최하위의 우선순위 수준으로 매핑되어 진다 .
스레드 우선순위가 스레드 사이에 관계를 정의하는 것을 염두에 두는 것은 중요
하다 . 다른 중요한 스레드가 더 낮은 우선순위로 실행한다면 , 높은 스레드 우선
순위를 할당하는 것은 그 시스템에 해로울 수 있다 . 사용자는 더 낮은 우선순위
값을 사용함으로써 더 좋은 응용 프로그램 동작을 달성할 지도 모른다 . 다른 우
선순위 값을 가진 성능 검사는 응용 프로그램이나 드라이버에 스레드를 위한 가
108 제 3장 시스템 프로그래밍 실행
장 좋은 우선순위 수준을 확인하는 것은 신뢰할 수 있는 방식이다 . 그러나 다른
256 우선순위 값을 검사하는 것은 효율적이지 못하다 . 표 3-10 에 나열된 바와
같이 드라이버나 응용 프로그램의 목적에 따라 스레드의 적절한 우선순위 범위
를 선택한다 .
스레드의 일시 중지 및 다시 시작시간 소모적인 초기화 루틴들이나 다른 요소들에 의존적인 어떤 조건적 작업들
을 지연시키는 것은 시스템 성능 개선에 도움이 된다 . 결국 , 루프에 들어가
10,000 번의 검사를 한 후에야 필요로 하는 구성 요소가 준비된다는 것은 효율적
이지 못하다 . 더 나은 접근은 0.010 초와 같은적절한 시간만큼 작업자 스레드
(worker thread) 를 수면 상태로 두고 . 그 시간 후에 종속성의 상태를 검사한다 .
그리고 조건이 허락할 때 다른 0.010 초 동안 Sleep 으로 돌아가거나 계속해서 프
로세스한다 . 스레드를 정지시키고 다시 시작하기 위해서 스레드 내부자신안에
Sleep 함수를 사용한다 . 또한 다른 스레드를 통해 스레드를 제어하기 위해
SuspendThread 와 ResumeThread 를 사용할 수 있다 .
Sleep 함수는 밀리세컨드 (millesecond) Sleep 간격을 지정하는숫자 값을 사용
한다 . 아마 실제적인 Sleep 간격이 이 값을 초과할 것이라는 것을 기억하는 것은
중요하다 . Sleep 함수는 현재 스레드 퀀텀의 나머지를 스케쥴러에 넘기고 스케
줄러는 지정된 간격이 지났고 높은 우선순위의 어떤 다른 스레드가 있지 않을 때
까지 이 스레드에게 다른 시간 분할을 주지 않을 것이다 . 예를 들면 , Sleep(0) 으
로 호출된 함수는 0 밀리세컨드의 Sleep 간격을 암시하지 않는다 . 그 대신에 ,
Sleep(0) 은 다른 스레드로 현재의 퀀텀의 나머지를 포기한다 . 스케줄러가 스레
드 리스트에 있는 같거나 또는 높은 우선순위로 어떤 다른 스레드를 가지고 있지
않는다면 , 그 현재의 스레드는 단지 계속해서 실행할 것이다 .
Sleep(0) 호출과 유사하게 . SleepTillTick 함수는 현재 스레드의 퀀텀 나머지를
포기하고 다음의 시스템 틱까지 스레드를 일시 정지시킨다 . 이는 시스템 틱 기초
표 3-10 스레드 우선순위 범위
범위 설명
0 through 96 # 실시간 드라이버들에 예약
.
97 through 152 디폴트 장치 드라이버들에 의해 사용 .
153 through 247 실시간에 못미치는 드라이버들에 예약한다 .
248 through 255 응용 프로그램을 위한 비 실시간 우선순위로 매핑 .
제 3 과 : 스레드와 스레드 동기화 구현 109
방식으로 이는태스크를 동기화하고자 할 때 유용하다 . WaitForSingleObject 이
나 WaitForMultipleObjects 함수는 다른 스레드나 동기화 객체가 신호될 때까지
스레드를 정지시킨다 . 예를 들면 , WaitForSingleObject 함수가 그 대신에 활성
화 된다면 , 스레드는 반복된 Sleep 과 GetExitCodeThread 호출로 루프에 들어
가지 않고 종료하기 위해 다른 스레드를 기다릴 수 있다 . 이 방법은 리소스의 더
좋은 사용결과를 낳고 코드 가독성을 향상시킨다 . 시간 초과 (timeout) 값을 밀리
세컨드 (millisecond) 단위로 WiatForSingleObject 와 WaitForMultipleObjects
함수로 전달이 가능하다 .
스레드 관리 예제 코드다음과 같이 발췌된 코드는 스레드가 일시 중지 모드로 어떻게 생성되는지 , 스레
드 함수와 매개변수의 지정 , 스레드 우선 순위의 변경 , 스레드의 다시시작 , 그리
고그 프로세스가 끝날 때 까지 동작하는 쓰레드를 기다린 다음 마지막으로 종료
한다 . 마지막 단계에서 , 다음의 발췌된스레드 함수로부터 리턴된 에러 코드를 어
떻게 검사하는지를 보여준다 .
// Structure used to pass parameters to the thread.
typedef struct
{
BOOL bStop;
} THREAD_PARAM_T
// Thread function
DWORD WINAPI ThreadProc(LPVOID lpParameter)
{
// Perform thread actions...
// Exit the thread.
return ERROR_SUCCESS;
}
BOOL bRet = FALSE;
THREAD_PARAM_T threadParams;
threadParams.bStop = FALSE;
DWORD dwExitCodeValue = 0;
// Create the thread in suspended mode.
HANDLE hThread = CreateThread(NULL, 0, ThreadProc,
(LPVOID) &threadParams,
CREATE_SUSPENDED, NULL);
if (hThread == NULL)
{
// Manage the error...
}
else
{
// Change the Thread priority.
110 제 3장 시스템 프로그래밍 실행
CeSetThreadPriority(hThread, 200);
// Resume the thread, the new thread will run now.
ResumeThread(hThread);
// Perform parallel actions with the current thread...
// Wait until the new thread exits.
WaitForSingle׊к(hThread, INFINITE);
// Get the thread exit code
// to identify the reason for the thread exiting
// and potentially detect errors
// if the return value is an error code value.
bRet = GetExitCodeThread(hThread, &dwExitCodeValue);
if (bRet && (ERROR_SUCCESS == dwExitCodeValue))
{
// Thread exited without errors.
}
else
{
// Thread exited with an error.
}
// Don’t forget to close the thread handle
CloseHandle(hThread);
}
스레드 동기화 하기다중 스레드 프로그래밍의 실질적인 기술은 교착 상태 방지 , 리소스 접근 보호 ,
확실한 스레드 동기화에 달려있다 . Windows Embedded CE 는 드라이버나 응
용프로그램에서여러 스레드들의 리소스 액세스 동기화를 위해 크리티컬 섹션
(Critical Section), 뮤텍스 (Mutex), 세마포어 (Semaphore), 이벤트 (Event) 그
리고 인터락 (Interlock) 함수들과 같은 커널 오브젝트 (Kernel Object) 들을 제
공하며 , 개체의 선택은 어떤 작업을 수행 하느냐에 달려있다 .
크리티컬 섹션 (Critical Section)
크리티컬 섹션은 단일 프로세스에서 리소스들의 액세스를 보호하고 스레드들을
동기화하는 오브젝트 ( 개체 ) 이다 . 크리티컬 섹션은 프로세스들끼리 공유할 수
없으며 . 크리티컬 섹션에 의해 보호되는 리소스를 액세스 하려면 , 스레드는
EnterCriticalSection 함수를 호출한다 . 이 함수는 크리티컬 섹션이 사용 가능
할 때 까지 스레드를 차단한다 .
제 3 과 : 스레드와 스레드 동기화 구현 111
경우에 따라서 , 스레드의 실행을 차단하는 것은 효과적인 방법이 아닐 수 가 있
는데 , 예를 들면 , 사용 가능하지 못할 옵션 리소스를 사용하고자 할 때 ,
EnterCriticalSection 함수를 호출하면 옵션 리소스에서 아무런 처리를 수행하지
않은채 커널 리소스를 소비하고 스레드를 차단한다 . 이런 경우는
TryEnterCriticalSection 함수를 호출함으로써 차단없이 크리티컬 섹션을 사용
하는 것이 효과적이다 . 이 함수는 크리티컬 섹션을 획득하려고 시도하고 크리티
컬 섹션이 사용될 수 없다면 즉시 리턴한다 . 접속 불량인 장치를 다시 연결하라
고 하거나 사용자에게 . 입력 하라는 프롬프트등을 통하여 스레드는 다른 코드 경
로로 계속해서 진행 할 수 있다 .
EnterCriticalSection 또는 TryEnterCriticalSection 으로 크리티컬 섹션을 획득
하려 할 때스레드는 리소스에독점적으로 접근할 수 있다 . 현재의 스레드가
LeaveCriticalSection 함수를 불러 크리티컬 섹션 개체를 릴리스 하지 않는 한
다른 스레드는 이 리소스에 액세스 할 수 없다 . 이 외에도 , 이 방식은 스레드를
종료하기 위하여 왜 TerminateThread 함수를 사용하면 안되는지에 대하여 잘
강조하여 주고 있다 . TerminateThread 는 정리 (cleanup) 를 수행하지 않는다 .
만일 종료된 스레드가 크리티컬 섹션을 소유한다면 , 보호된 리소스는 사용자가
응용프로그램을 다시 시작 할 때 까지 사용이 불가능 하게 된다 .
표 3-11 은 스레드 동기화의 목적을위해 크리티컬 섹션과 함께 동작하는 가장 중
요한 함수들을 보여준다 .( 나열한 것이다 ).
뮤텍스 (Mutex)크리티컬 섹션은 단일 프로세스에 한정된 반면에 , 뮤텍스는 다중 프로세스들간
에 공유된 리소스들을 상호 배타적으로 액세스 하도록 조정한다 . 뮤텍스는 상
호 프로세스 동기화 (inter-process synchronization) 을 용이하게 하는 커널 오
브젝트이다 . 뮤텍스를 생성하기 위해 CreateMutex 함수를 호출하며 생성시 뮤
텍스 오브젝트의 이름을 지정할 수도 있지만 이름이 없는 뮤텍스 생성도 가능하
표 3-11 중요 섹션 API
함수 설명
InitializeCriticalSection 크리티컬 섹션 개체 생성 및 초기화 .
DeleteCriticalSection 크리티컬 섹션 개체 소멸 .
EnterCriticalSection 크리티컬 섹션 개체 ( 개체 ) 획득 .
TryEnterCriticalSection 크리티컬 섹션 개체를 획득하려 시도
LeaveCriticalSection 크리티컬 섹션 개체 해제
112 제 3장 시스템 프로그래밍 실행
다 . 다른 프로세스의 스레드는 CreateMutex 를 호출하고 동일한 이름을 명시
할 수 있다 . 그렇지만 이러한 일연의 호출들은 새로운 커널 개체를 생성하지 않
는 대신 현존하는 mutex 를 처리하여 반환한다 . 이 시점에서 , 분리된 프로세스
들내 스레드들은 보호된 공유 리소스의 액세스 ( 접근 ) 을 동기화하기 위해 뮤텍
스 오브젝트를 사용할 수 있다 .
어떠한 스레드도 뮤텍스 오브젝트를 소유하지 않으면 그 뮤텍스 오브젝트는 시
그널된 (signaled) 상태가 되고 하나의 스레드라도 소유권을 가지면 시그널되지
않은 (nonsignaled) 상태가 된다 . 스레드는 소유권을 요청 하기 위해서는 반드시
대기 함수인 WaitForSingleObject 또는 WaitForMultipleObject 중의 하나를 사
용하여야 한다 . 대기 기간 동안 mutex 를 사용 할 수 없을 경우 스레드는 시간 초
과 값을 지정함으로써다른 ( 대체 ) 코드 경로로 스레드의 처리 (thread
processing) 을 재기할 수 있다 . 반면에 , mutex 가 사용 할수있고 현 스레드에
소유권이 주어졌을 경우 , 다른 스레드를 위하여 mutex 개체를 릴리즈하기 위하
여 뮤텍스 (mutex) 가 기다리는 동안 " 으로 변경 요청 ReleaseMutex 를 호출하
는 것을 잊지 말아야 한다 . 이것은 자기 자신의 쓰레드 실행 없이 반복적으로 루
프에서만 동작하는 경우와 마찬가지로 하나의 쓰레드가 여러번 호출될 때 함수
가 기다려야 하기 때문에 중요하다 ." 로 변경 요청함 . 시스템은 교착 상태에 빠
지는 것을 방지 하지 위해서소유한 스레드를
차단하지 않으나 스레드는 뮤텍스를 릴리즈하기 위해 대기 함수만큼 여러번
ReleaseMutex 를 호출 해야 한다
표 3-12 는 스레드 동기화 목적으로 뮤텍스 오브젝드를 사용하는 가장 중요한
함수들을 나열한 것이다 .
표 3-12 Mutex API
함수 설명
CreateMutex 명명된 (named) 뮤텍스 오브젝트와 명명되지 않은(unnamed) 뮤텍스 오브젝트를 생성하고 초기화 한다 . 프로세스들간에 공유된 리소스를 보호하기 위해서는 명명된 뮤텍스 오브젝트를 사용해야 한다 .
CloseHandle 명명된 (named) 뮤텍스 오브젝트와 명명되지 않은(unnamed) 뮤텍스 오브젝트를 생성하고 초기화 한다 . 프로세스들간에 공유된 리소스를 보호하기 위해서는 명명된 뮤텍스 오브젝트를 사용해야 한다 .
WaitForSingle 개체 단일 mutex 개체의 소유 지분의 허용을 단일 뮤텍스 오브젝트의 소유권을 얻기위해 대기한다
제 3 과 : 스레드와 스레드 동기화 구현 113
세마포어커널 오브젝트가 프로세스내 그리고 프로세스들간의 리소스의 상호 배타적인 액
세스 ( 접근 ) 을 제공하는 것과는 별도로 , 윈도우 임베디드 CE 는 단일 또는 다중
프로세스들이 리소스를 동시에 액세스하도록 하는 세마포어 오브젝트를 제공한
다 . 이러한 세마포어 오브젝트들은 리소스에 액세스하는 스레드의 숫자들을 제
어 하기 위하여 0 에서 최대값을 가지는 카운터를 보유하고 있다 . 최대 값의 양
은 CreateSemaphore 함수호출로 결정된다 .
세마포 카운터는 동기화 개체를 동시에 액세스하는 스레드의 숫자를 제한 한다 .
시스템은 세마포 개체의 값이 0 에 도달하고 신호받지 않은 상태일때까지 스레
드가세마포어 오브젝트의 대기를 완료할 때마다 카운터 값을 감소시킨다 . 카운
터는 0 이하로 감소 될 수 없다 . 세마포어를 릴리즈 하기위한
ReleaseSemaphore 함수를 불러오기 전 까지 스레드는 리소스에 액세스 할 수
없으며 , 지정된 값까지 카운터를 증가시킬 수 있으며 세마포 개체를 신호된 상태
로 바뀐다 .
뮤텍스와 마찬가지로 , 다중 프로세스들은 프로세스들간에 공유된 리소스를 액세
스하기 위해 동일한 세마포어 오브젝트의 핸들들을 열수 있다 .
CreateSemaphore 함수에 대한 첫 호출은 지정된 이름의 세마포어 오브젝트를
생성한다 . 지명 되지 않은 세마포 개체를 구성 할 수 있으나 이 개체의 경우상호
프로세스 동기화에는 사용 할 수 없다 . 동일한 이름으로 CreateSemaphore 함
수에 대한 후속 호출은 새로운 개체를 생성할 수 없으나 동일한 세마포의 새 핸
들을 열 수 있다 .
표 3-13 는스레드 동기화를 목적으로 세마포어 오브젝트와 관련있는 중요한 함
수들을 중요한 순서대로 나열 한 것이다 .
WaitForMultiple 개체 단일 또는 다중 뮤텍스 오브젝트에 대한 소유권을 얻기위해 대기한다
ReleaseMutex 뮤텍스 오브젝트를릴리스 한다 .
표 3-12 Mutex API
함수 설명
114 제 3장 시스템 프로그래밍 실행
이벤트 (Event)이벤트 오브젝트는 스레드들을 동기화하는 또다른 커널 오브젝트이다 . 이 개체
는 작업이 끝났거나 판독기에 데이타가 주어졌을때 응용프로그램이 다른 스레
드에게 신호를 보낼 수 있는 작업을 할 수 있게 하여준다 . 각 이벤트는 API 를 사
용하여 이벤트의 상태를 식별 하는데 사용되는 시그널된 / 시그널되지 않은
(signaled/non-signaled) 상태 정보를 가지고 있다 . 이벤트의 예정된 행동 (-)
에 따라 수동 이벤트(manual event)와 자동-재설정 이벤트(auto-reset event)
가 생성된다 .
이벤트 오브젝트 생성시 스레드 생성은 이 이벤트의 이름을 명시할 수 있지만 이
름이 없는 이벤트 생성도 가능하다 . 다른 프로세스들에서 스레드들이
CreateEvent 를 호출하고 동일한 이름을 지정할 수 있지만 이러한 일련의 호출
들은 새로운 커널 오브젝트들을 생성하지는 않는다 .
표 3-14 는 스레드 동기화 목적으로 이벤트 오브젝트들에 대한 중요한 함수들을
나열한 것이다 .
표 3-13 세마포 API
함수 설명
CreateSemaphore 카운터 값과 함께 명명된 세마포 개체와 명명되지 않은 세마포 개체의 생성과 초기화 . 명명된 세마포 개체를 사용하여 프로세스 사이에서공유 리소스 보호하기 .
CloseHandle 세마포어 핸들 닫기고 세마포어 오브젝의 참조를 삭제 .세마포어의 모든 참조들은 커널이 세마포어 오브젝트를 삭제하기전에 개별적으로 닫혀져야 한다 .
#WaitForSingleObject 단일 세마포어 오브젝트의 소유권을 얻기 위해 대기 .
WaitForMultipleObjects 단일 또는 다중 세마포어 오브젝트들의 소유권을 얻기 위해 대기 .
ReleaseSemaphore 세마포어 오브젝트 해제 .
표 3-14 이벤트 API
함수 설명
CreateEvent 이름있는 또는 이름없는 이벤트 오브젝트의 생성과 초기화
SetEvent 이벤트 신호 ( 아래 참조 )
제 3 과 : 스레드와 스레드 동기화 구현 115
이벤트들의 API 행동 ( 동작 속성 ) 은 이벤트들이 적용된 종류에 따라 다르다 . 수
동 이벤트 오브젝트 (manual event object) 로 SetEvent 를 사용할 때 , 그 이벤
트는 ResetEvent 가 명시적으로 호출 될 때 까지 신호받은 상태 (signaled) 된 상
태로 있다 . 자동 - 재설정 이벤트로 신호 받는 상태에서 신호 받은 않은 상태로
즉시 전이되기 전 , PulseEvent 함수를 사용할 때 기껏해야 대기중인 하나의 스
레드가 해제된다 . 수동 스레드의 경우 , 대기중인 모든 스레드는 해제되고 곧 신
호되지 않은 상태로 전이된다 .
Inter-locked”라고 변경 요청함함수다중 스레드 환경에서 , 스레드들은 언제든지 멈추거나 스케쥴러에 의해 재기될
수 있다 . 코드의 일부분이나 응용프로그램의 리소스들은 세마포 , 이벤트 , 크리
티컬 섹션들을 사용하여 보호될 수 있다 . 어느 응용 프로그램에서는 한 줄의 코
드를 보호하기 위하여 이 시스템 오브젝트들을 사용한다는 것은 매우 시간 소모
적인 것이 될 수 있다 .
// Increment variable
dwMyVariable = dwMyVariable + 1;
위의 예제 코드는 C 의 단일 명령문이나 어셈블리에서는 여러 개의 명령문이 될
수도 있다 . 이 특정한 샘플의 경우 , 스레드는 작업 도중에 정지하고 다시 실행
할 수 있으나 다른 스레드가 동일한 변수를 사용할 경우 에러가 잠재적으로 발생
할 수 있다. 이 동작은 윈자성(atomic)이 아니다. 다행이도 Windows Embedded
CE 6.0 R2 에서는 동기화 오브젝트들을 사용하지 않고 안전하고 , atomic 한 동
작들로 다중 스레드 환경에서 값들을 증가 , 감소 , 추가 할 수 있다 . 이는 상호 잠
금 함수들을 사용하여 이루어진다 .
표 3-15 변수들을 atomically 하게 조작하는데 사용되는 가장 중요한 상호 잠금
함수들을 나열한 것이다 .
PulseEvent 이벤트 펄스와 신호 ( 아래 참조 )
ResetEvent 신호된 이벤트 재 설정
WaitForSingleObject 이벤트가 신호받기를 대기
WaitForMultipleObjects 이벤트가 단일 혹은다중 이벤트 오브젝트들에 의해 신호받기를대기
CloseHandle 이벤트 개체 해제
표 3-14 이벤트 API
함수 설명
116 제 3장 시스템 프로그래밍 실행
스레드 동기화 문제해결삭제다중 스레드 프로그래밍은 (Multithreaded programming) 상호 작용 인터페이스
와 백그라운드 작업을 위한 실행분리된 코드 실행 단위를 기반으로한 소프트웨
어 솔루션을 구성하게 하여 준다 . 이 것은 고급 ( 진보된 ) 개발 기술로서 스레드
동기화 방식에서주의깊은 구현을 요구한다 . 루프나 서브루틴에서 다중 동기화
개체를 사용할 경우 교착 상태 가 발생 할 수 있다 . 예를 들면 , 스레드 1 은 뮤텍
스 A 를 소유하고 있고 뮤텍스 A 를 해제하기 전에 뮤텍스 B 를 기다리고 있다 .
반면에 스레드 2 는 뮤텍스 B 를 해제하기 전에 뮤텍스 A 를 기다리고 있다 . 이
경우 두 스레드는 리소스를 서로 릴리즈 하여야 하는 상황에 의존 하기때문에 계
속 진행을 할 수 없다 . 특히 , 다중 프로세스들의 스레드들이 공유된 리소스들을
접근 할 경우오류를 발견하거나 처리하기가 어렵다 .
Remote Kernel Tracker 도구는 시스템상에서스레드들이 어떻게 스케쥴링되었
는지와교착상태를 찾을 수 있게 도와 준다 . Remote Kernel Tracker 도구 는대
상 장치상의 모든 프로세스 , 스레드 , 스레드 상호작용 , 다른 시스템의 동작을 감
시 할 수 있다 . 이 도구는 CeLog 이벤트 - 추적 시스템에 의존 하며 ,
%_FLATRELEASEDIR% 디렉터리에서 Celog.clg 파일을 통해 커널과 다른 시
스템 이벤트를 로그 할 수 있다. 시스템 이벤트는 영역에 의하여 분류된다. CeLog
이벤트 시스템 - 추적 시스템은 테이터 로깅을 위하여 특정 영역에만 집중 할 수
있도록 설정 될 수 있다 .
만일 대상 장치에서 Kernel Independent Transport Layer (KITL) 이 활성화 되
면 , Remote Kernel Tracker 는 CeLog 테이터 그리고 스레드와 프로세스의 상
호작용의 분석을 표시 한다 . 이 것은 그림 3-4 에서 서술 하며 . KITL 이 Remote
Kernel Tracker 도구에 테이터를 직접 전송 할때 , 오프라인에서 수집한 테이터
를 분석 가능케 하여 준다 .
표 3-15 연동된 API
함수 설명
InterlockedIncrement 32 비트 변수의 값을 증폭
InterlockedDecrement 32 비트 변수의 값을 감소
InterlockedExchangeAdd 하나의값을 추가하여 수행함
제 3 과 : 스레드와 스레드 동기화 구현 117
그림 3-4 Remote Kernel Tracker 도구
참고 CeLog 이벤트 추적과 필터링
CELOG 이벤트의 추적과 필터링의 추가 정보는 마이크로소프트사의 MSDN 웹싸이트 http://msdn2.microsoft.com/en-us/library/aa935693.aspx 에 있는 WINDOWS EMBEDDED CE 6.0 문서의“CELOG 이벤트 추적 개요” 섹션을 참조 .
학습 요약Windows Embedded CE 는 다중스레드운영 체제로서 스레드와 프로세스를 생
성 할 수 있도록 여러 개의 프로세스 관리 함수를 제공하며 , 스레드의 우선 순위
인 0 부터 255 까지의 값을 할당하고 , 스레드를 일시 중지하며 , 그리고 스레드
를 재 실행한다 . 수면 함수 ( 슬립함수 ) 는 일정한 기간동안 스레드를 중단시키
는데 유용하며 , WaitForSingleObject 또는 WaitForMultipleObjects 함수 역시
다른 스레드나 동기화 개체가신호 받기까지스레드를 중단 할 수 있다 . 프로세스
와 스레드는 2 가지 방법으로 종료 될 수 있다 : 정리된것과 정리되지 않은 방법 .
일반적인 규칙으로는 , 항상 ExitProcess 와 ExitThread 를 사용하여 시스템이
정리를 실행 할 수 있도록 한다 . 만약 , 다른 방법이 전혀 없다면
TerminateProcess 와 TerminateThread 를 사용한다 . 다중 스레드를 사용 할
경우 , 프로세스 간에 공유하는 리소스에 액세스 하기 위해서는 스레드 동기화를
구현하는 것이 유용하다 . Windows Embedded CE 는 이러한 목적을 위해 크리
티컬 섹션 , 뮤텍스 그리고 세마포어의 여러 커널 오프젝트들을 제공한다 크리티
118 제 3장 시스템 프로그래밍 실행
컬 섹션은 단일 프로세스에서 리소스에 액세스 하는 것을 보호한다 . 뮤텍스는 다
중 프로세스들간에 공유된 리소스들을 상호 배타적인 액세스를 조정한다 . 세마
포어는 프로세스내 그리고 프로세스들간의 리소스들을 다중 스레드들이 동시에
억세스하게 해준다 . 이벤트는 다른 스레드에 알리는데 사용되며 , 상호 잠금 함
수는 thread-safe atomic 한 방법으로 변수들의 처리에 사용된다 . 만일 , 개발
단계에서교착 상태 (deadlock) 과 같은 스레드 동기화 문제가 발생하면 , CeLog
이벤트 추적기 (event-tracking) 시스템과 Remote Kernel Tracker(Remote
Kernel Tracker) 를 사용하여 대상 장치 상에서의 스레드의 상호작용을 분석한
다 .
시험 팁
이 인증 시험에 합격 하기 위해서는 , WINDOWS EMBEDDED CE 6.0 R2 에서 여러 동기화 개체를 사용 하는 방법을 잘 이해 하여야 한다 .
학습 4: 예외 처리 구현 119
학습 4: 예외 처리 구현윈도우 임베디드 CE 가 동작하고 있는 대상 장치는 시스템과 응용 프로그램의 처
리의 일부분으로서 예외들을 포함하고 있다 . 이 시도는 적절한 방법으로 예외들
에 응하는 것이다 . 올바른 예외 처리는 긍정적인 사용자 경험과 운영 체제가 안
정적으로 잘 지속되도록 돕는다 . 예를 들어 , 만일 카메라가 현재 연결이 되지 않
았을 경우, 예상치 못한 비디오 응용프로그램이 종료되는 대신, Universal Serial
Bus (USB) 를 연결하라는 지시를 사용자에게 지시하는 것이 더 유용 할 것이다 .
그러나 , 예외 처리는 종합적인 솔루션으로 사용하여서는 안된다 . 예상치 못한 응
용 프로그램 동작은 실행 파일 , DLL, 메모리 구조 그리고 데이터를 변경하는 악
성 코드로 만든다 . 이 경우 , 제대로 작동하지 않는 컴포넌트나 응용프로그램을
종료하는 것이 시스템과 데이터의 보호를 위하여 가장 좋은 방법이라 할 수 있겠
다 .
이 과정을 마치면 사용자는 다음을 할 수 있다 .
■ 예외가 발생되는 윈인 이해” 으로 변경 요청
■ catch 와 throw 로 예외 처리하기” 으로 변경 요청
예상 학습시간 : 30 분 .
예외 처리 개요예외 (Exceptions) 는이벤트로서 에러 조건으로부터 온 결과이다 . 이 조건들은
프로세스나 운영체제 , 응용프로그램들이 커널 모드와 사용자 모드에서 일반 흐
름의제어 밖에서 실행할 경우 발생한다 . 예외를 알리거나 처리함으로 사용자의
긍정적인 경험과 응용프로그램의 견고성을 증가 시킬 수 있다 . 그렇지만 엄격
히 말해서 , 구조화된 예외 처리는 윈도우 임베디드 CE 의 필수적인 부분이기 때
문에 코드내의 예외 처리기 (exception handler) 를 구현할 필요는 없다 .
운영 체제는 모든 예외들을 감지하고 나서 응용 프로그램 프로세스들에게 그 이
벤트들의 윈인을 보낸다 . 만일 프로세스가 예외 이벤트를 처리하지 않을 경우 ,
시스템은그 예외를 검시 디버거 (Postmortem debugger) 로 전달하며 , 프로세
스를 최종적으로 종결함으로써 하드웨어나 소프트웨어의 오류작동으로부터 시
스템을 보호한다 . Dr. Watson 은 메모리 덤프 파일을 생성하는 윈도우 임베디드
CE 의 일반적인 검시 디버거다 .
예외 처리와 커널 디버깅예외처리는 커널 디버깅의 기초가 된다 . 운영체제 디자인에서 커널 디버깅을 활
성화 하면 , 플랫폼 빌더는 런타임 - 이미지에 kdStub 포함하는데 이는 컴포넌트
120 제 3장 시스템 프로그래밍 실행
가 디버거 에서 중단되는 것에 대한 예외 처리를 한다 . 이 경우를 분석 하려면 ,
코드를 점검하고 프로세스을 재 실행한 다음 응용프로그램 프로세스를 수동적으
로 종료한다 . 하지만 , 대상 장치와 상호작용을 위해서는 개발 워크스테이션에
KITL 연결을 필요로한다 . KITL 연결 없이 디버거는 예외를 무시하고 응용프로
그램이 계속 실행하도록 내버려두며 디버거가 사용중이 아닐때는 운영 시스템이
다른 예외 처리기를 사용하도록 한다 . 만일 응용프로그램이 예외 처리를 하지 않
는다면 , 운영 체제는 커널 디버거로 하여금 재 기회를 주어 검시디버깅을 실행하
도록 한다 . 여기서 , JIT (just in time) 디버깅이라 한다 . 디버거는 디버거 출력
을 위해서 예외를 수락하여야 하며 KITL 연결을 기다려야 한다 . Windows
Embedded CE 는 KITL 연결이 될 때까지 기다리게 되며 연결이 되면대상 장치
를 디버깅하기 시작한다 . 개발자 문서에는 종종 첫번째 기회 예외 (fitst-chance
exception) 과 두번째 기회 예외 (second-chance exception) 이라는 용어를 사
용하는데 이는 커널 디버거가 이런 경우 예외를 처리하는데 2 번의 기회를 가지
기 때문이다 . 그렇지만 , 사실 동일한 예외 이벤트를 참조한다 . 시스템 검사와 디
버깅에 대한 자세한 정보는 제 5 장 “디버깅과 시스템 검사” 를 참조한다 .
하드웨어 와 소프트웨어 예외Windows Embedded CE 는모든 하드웨어 및 소프트웨어 예외들에 대해 동일한
구조화된 예외 처리 (SHE:Structured Exception Handling) 접근법을 사용한다 .
CPU 는 0 으로 나누거나 유효하지 않은 메모리 주소를 액세스하려고 시도할 때
발생하는 접근 위반 (access violation) 과 같은 유효하지 않은 일련의 명령어들
에 관련하여 하드웨어 예외들을 유발한다 . 반대로 드라이버들 , 시스템 응용 프
로그램들 , 사용자 응용 프로그램들은 RaiseException 함수를 이용한 운영 체제
의 SHE 메커니즘을 불러내 소프트웨어 예외들을 유발한다 . 예를들면 , 필요한
장치를 액세스 할 수 없는 경우 (USB 카메라나 데이터 베이스 연결 ), 사용자가
유효하지 않은 명령줄 (command-line) 매개 변수를 지정했을 경우 또는 일반적
인 코드 경로밖에서 특별한 명령들을 수행하는 어떠한 경우에 있어서 예외를 유
발 시킬 수 있다 . 예외 처리를 설명하여주는정보를 지정하기 위해
RaiseException 함수 호출에 여러 매개변수를 지정할 수 있다 . 그리고 나서 이
러한 지정은 예외처리기 (exception handler) 이 필터 식으로 사용될 수 있다 .
예외 처리기 구문 Windows Embedded CE 는 프레임 기반의 구조화된 예외 처리를 지윈한다 . 일
련의 민감한 코드를 중괄호 ({}) 안에 넣고 __try 키워드로 표시 할수 있는데 이
키워드는 . 그 코드의 실행도중 예외가 발생하였을때 __exception 키워드를 사용
하여 표시된 예외 처리기를 호출한다 . Microsoft Visual Studio 에 포함된 C/
C++ 컴파일러는이러한 키워드들을 지윈하며 시스템이 기계 상태를 복귀하고 예
학습 4: 예외 처리 구현 121
외가 발생한 지점에서 스레드 실행을 계속할 수 있게 하거나 예외 처리기에 제어
를 전달하고 제외 처리기가 위치한 call stack frame 에서 스레드 실행을 계속 할
수 있게 한다 .
다음 코드 부분은 구성된 예외 처리를 위하여 __try 와 __except 키워드를 어떻
게 사용 하는지를 보여준다 .:
__try
{
// Place guarded code here.
}
__except (filter-expression)
{
// Place exception-handler code here.
}
The __except 키워드는 단순 식이나 필터 함수 같은 필터 식을 지윈하며 , 필터
식은다음 값들 중의 하나로 평가된다 .:
■ EXCEPTION_CONTINUE_EXECUTION 시스템은 예외가 해결된 것임
을 가정하고 예외가발생했던 지점에서 스레드의 실행을 계속한다 . 일반적
으로 필터 함수들은 평상시와 마찬가지로 프로세싱을 지속하기 위해 예외
처리후 이 값을 리턴한다 .
■ EXCEPTION_CONTINUE_SEARCH 시스템은 계속해서 적절한 예외 처
리기를 검색한다 .
■ EXCEPTION_EXECUTE_HANDLER 시스템 스레드는 예외가 발생한 지
점에서부터 보다는 예외 처리기에서부터 순차적으로 계속해서 실행된다 .
참고 예외 처리 지윈
예외 처리는 C 언어에서의 확장이지만 C++ 언어 고유의 것을 지윈하지는 않는다 .
종료 처리기 구문Windows Embedded CE 는 종료 처리를 지윈한다. C 와 C++ 언어의 Microsoft
확장으로서 , 시스템이 보호된 코드 블럭에서 제어의 어떻게 벗어나는지에 관계
없이 특정한제어의 # 실행 할 수 있도록 하여 준다 . 이 코드 섹션을 종료 처리기
라 하며 , 보호된 코드에서예외나 다른 어떤 에러가 발생하였을때 정리 작업을코
드 블록을 항상실행한다 . 예를 들면 , 더 이상 필요하지 않은스레드 핸들들을 닫
기위해 종료 ( 종결 ) 처리기를 사용할 수 있다
다음 코드 부분은 구조화된 예외 처리에 대한 __try 와 __fin#ally 키워드사용 방
법을 보여준다 :
122 제 3장 시스템 프로그래밍 실행
__try
{
// Place guarded code here.
}
__ finally
{
// Place termination code here.
}
종료 처리는 보호된 섹션에서 __leave 키워드를 지윈한다 . 이 키워드는 보호된
섹션에서 현재 위치의 스레드의 실행을 종료하며호출 스택 (call stack) 을 해제
하지 않고 종료 처리기의 첫 구문에서 스레드를 재 실행하도록 한다 .
참고 __try, __except, 와 __finally 블럭 사용하기
단일 __TRY 블럭은 예외 처리기와 종료 처리기 모두를 소유 할 수 없다 . 만일 , __EXCEPT 와__FINALLY 둘 다를 사용 하여야 할 경우 외부의 TRY-EXCEPT 구문 과 내부의 TRY-FINALLY 구문을 사용한다 .
동적 메모리 할당동적 메모리 할당은 시스템에서 커밋된 메모리 페이지의 총 수를 줄이는데구조
화된 예외 처리에 의존하는 할당 테크닉이다 . 이 기술은 특히 큰 메모리할당하는
데 유용하다 . 커밋 전 (Pre-committing) 의 전체의 할당은 시스템으로 하여금 커
밋 할 수 있는 페이지가 부족하게하며 가상 메모리의 할당을 실패하게하는 결과
를 초래한다 .
동적 메모리 할당의 기술은 다음과 같다 :
1. 메모리 블록을 예약하기 위해 NULL 베이스 주소로 VirtualAlloc 를 호출한
다 . 시스템은 페이지를 커밋하지 않은 상태로 이 메모리 블럭을 예약한다 .
2. 메모리 페이지 접근 ( 액세스 ) 을 시도하기 . 이 것은 예외를 유발시키는데 왜
냐하면 커밋하지 않은 페이지를 읽거나 쓸 수 없기 때문이다 . 이 불법 작업
은 페이지 폴트 예외 (page fault exception) 를 유발한다 . 그림 3-5 와 3-
6 은 PageFault.exe 로 불리는 응용프로그램을 실행하였을때처리되지 않은
페이지 폴트 결과를 보여준다 .
3. 필터 함수를 기반으로 한 예외 처리기의 구현 . 예약된 영역으로부터 필터
함수에서 페이지커밋한다 . 만일 성공할 경우 , EXCEPTION_
CONTINUE_EXECUTION 를리턴하여 예외 가 발생한 지점의 __try 블럭
에서 스레드를 계속 실행한다 . 만일 , 페이지 할당이 실패하면 ,
EXCEPTION_EXECUTE_HANDLER 를 리턴하여 __except 블럭의 예외
처리기를 호출하고 예약되고 커밋된 페이지 전 영역을 해제한다
학습 4: 예외 처리 구현 123
그림 3-5 사용자 측면에서 처리되지 않은 페이지 폴트 예외
그림 3-6 Visual Studio 2005 에서 KITL 을 통한 처리되지 않은 페이지 폴트 예외의 디버그 출력이다
다음의 발췌된 코드는 페이지 폴트 예외 처리를 기초로한 동적 메모리 할당 테크
닉을 보여준다 .
#define PAGESTOTAL 42 // Max. number of pages
LPTSTR lpPage; // Page to commit
DWORD dwPageSize; // Page size, in bytes
INT ExceptionFilter(DWORD dwCode)
{
LPVOID lpvPage;
if (EXCEPTION_ACCESS_VIOLATION != dwCode)
{
// This is an unexpected exception!
// Do not return EXCEPTION_EXECUTE_HANDLER
// to handle this in the application process.
// Instead, let the operating system handle it.
return EXCEPTION_CONTINUE_SEARCH;
}
// Allocate page for read/write access.
lpvPage = VirtualAlloc((LPVOID) lpPage,
dwPageSize, MEM_COMMIT,
PAGE_READWRITE);
if (NULL == lpvPage)
{
// Continue thread execution
// in __except block.
124 제 3장 시스템 프로그래밍 실행
return EXCEPTION_EXECUTE_HANDLER;
}
// Set lpPage to the next page.
lpPage = (LPTSTR) ((PCHAR) lpPage + dwPageSize);
// Continue thread execution in __try block.
return EXCEPTION_CONTINUE_EXECUTION;
}
VOID DynamicVirtualAlloc()
{
LPVOID lpvMem;
LPTSTR lpPtr;
DWORD i;
BOOL bRet;
// Get page size on computer.
SYSTEM_INFO sSysInfo;
GetSystemInfo(&sSysInfo);
dwPageSize = sSysInfo.dwPageSize;
// Reserve memory pages without committing.
lpvMem = VirtualAlloc(NULL, PAGESTOTAL*dwPageSize,
MEM_RESERVE, PAGE_NOACCESS);
lpPtr = lpPage = (LPTSTR) lpvMem;
// Use structured exception handling when accessing the pages.
for (i=0; i < PAGESTOTAL*dwPageSize; i++)
{
__try
{ // Write to memory.
lpPtr[i] = 'x';
}
__except (ExceptionFilter(GetExceptionCode()))
{ // Filter function unsuccessful. Abort mission.
ExitProcess( GetLastError() );
}
}
// Release the memory.
bRet = VirtualFree(lpvMem, 0, MEM_RELEASE);
}
학습 4: 예외 처리 구현 125
학습 요약Windows Embedded CE 는 기본적으로 예외 처리와 종료 처리를 지윈한다 . 프
로세서 , 운영 체제 다음의 발췌된 코드는 페이지 폴트 예외 처리를 기초로한 동
적 메모리 할당 테크닉을 보여준다 부적절한 명령문의 순서 , 사용 가능하지 않은
메모리 주소의 액세스 시도 , 액세스 불가능한 장치 리소스들 , 유효하지 않은 매
개변수들 또는 동적 메모리 할당과 같은 특별한 처리를 요구하는 동작들에 대해
발생한다 . try-except 구문을 사용하여일반적인 제어 흐름에서 벗어난 예외 조
건에 대응 할수 있으며 , 보호된 __try 코드 블럭의제어 흐름에서 벗어 났더라도
try-finally 구문을 사용하여 항상 코드를 실행할 수 있게 한다 .
예외 처리는 발생된 이벤트들에 대해 ( 반응하여 ) 제어할 수 있도록 필터링 식
(filtering expression) 과 필터링 함수들을 제공한다 . 모든 예외들을 처리하는
것은 현명하지 못하다 . 왜냐하면 예상치 못한 응용프로그램의 실행이 오류코드
를 유발 할 수 있기때문이다 . 오직 신뢰할만하고 견고한 응용 프로그램의 행동들
에 대해서 직접적으로 처리되어져야 할 필요가 있는 예외들만 처리한다 . 운영 체
제는 메모리 덤프를 생성하거나 응용 프로그램 종결을 위해 처리되지 않은 예외
들을 검시 디버거 (postmortem debugger) 로 넘길 수 있다 .
시험 팁
이 인증 시험에 합격하기 위해서는 윈도우 임베디드 CE 6.0 에서의 예외 처리 (EXCEPTION HANDLING)와 종결 처리 (TERMINATION HANDLING) 의 사용법을 이해하여야 한다 .
126 제 3장 시스템 프로그래밍 실행
학습 5: 전윈 관리 구현전윈 관리는 Windows Embedded CE 장치에서 꼭 필요하다 . 전윈의 소비를 줄
임으로써 배터리의 수명을 연장 시킬 수 있으며 사용자에게 긍정적인 사용 경험
을 줄 수 있다 . 이 것은 휴대용 장치에서 전 # 윈 관리의 궁극적인 목표이다 . 고
정 장치 (Stationary device) 역시 전윈 관리를 통하여 향상될 수 있다 . 사용하
지않을 시 장치를 저 - 전력 상태로 전환하면 기기의 크기에 상관 없이 운영 경비
, 열 분산 , 기계적인 마멸 , 소음 수준등을줄일 수 있다 . 물론 , 효과적인 전윈관
리의 기능을 구현함으로 우리의 환경에 도움이 되는 것은 더 말 할 나위도 없다 .
이 과정을 마치면 사용자는 다음을 실행 할 수 있다 .
■ 대상 장치에서 전윈 관리
■ 응용프로그램에서 전윈 장치 기능 구현
예정된 학습 시간 : 40 분
전윈 관리 개요Windows Embedded CE 상에서 전윈 관리자 (PM.dll) 는 한 개의 커널 컴포넌트
로서 전윈 관리 기능을 구현하기 위하여 장치 관리자 (Device.exe) 와통합되어
있다 . 본질적으로 전윈 관리자는 커널 사이 , OEM 적응 계층 (OAL) ), 응용프로
그램 그리고 주변장치를 위한 드라이버에서 중개자로서의 역활을 한다 . 드라
이버와 응용 프로그램으로 부터 커널과 OAL 을분리시킴으로써 드라이버와 응용
프로그램은시스템 상태와는 별도로 드라이버와 응용프로그램은 각 자의 전윈 상
태를 관리 할 수 있다 . 드라이버들과 응용 프로그램들은 전윈 이벤트에 대한 알
림 (notification) 들을 받고 , 전윈 관리 함수들을 수행하기 위해 전윈 관리자와
인터페이스하고 있다 . 전윈 관리자는 이벤트들과 타이머들에 반응하여 시스템
전윈 상태를 설정하고 , 드라이버 전윈 상태를 제어하고 , 뱃터리 전윈 상태가 크
리티컬한 상태일때와 같은 전윈 상태 변경을 필요로 하는 OAL 이벤트들에 대응
할 수 있다 .
전윈 관리자 컴포넌트 와 아키텍쳐
전윈 관리자는 작업에따라 장치 인터페이스와 응용프로그램 인터페이스로 알림
인터페이스를 노출한다 . 알림 인터페이스는 응용프로그램으로 하여금시스템의
상태 또는 장치 전윈 상태가 변경되었을때 전윈 관리 이벤트의 정보를 수신 할 수
있게 하여준다 . 이러한 이벤트들에 반응하기 위해서는전윈 관리 가능하게 된 응
용 프로그램들은 시스템 전윈 상태를 변경하거나 전윈 관리 조건 (power
management requirement) 과 통신하기 위해 전윈 관리자와 상호 동작하는 응
학습 5: 전윈 관리 구현 127
용 프로그램 인터페이스 ( 를 사용한다 . 이와는 반대로 , 장치 인터페이스는 장치
드라이버들의 전윈 수준 (power level) 을 제어가 위한 메커니즘을 제공한다 . 전
윈 관리자는 시스템 전윈 상태와는 별도로 장치 전윈 상태를 설정할 수 있다 . 응
용 프로그램들과 유사하게 , 장치 드라이버들은 드라이버들의 전윈 요구 (power
requirement)를 다시 전윈 관리자와 통신하기 위해 드라이버 인터페이스(Driver
Interface) 를 사용한다 . 그림 3-7 에서 서술한 바와 같이 주요한 점은 전윈 관리
자와 전윈 관리자 API는 윈도우 임베디드 CE에서 전윈 관리를 중앙 관리화 한다.
그림 3-7 전윈 관리자와 전윈 관리 사이의 상호 작용
전윈 관리자 소스 코드Windows Embedded CE 는 개발자 컴퓨터에서 전윈 관리자를 위한 소스 코드가
포함되어 있는 %_WINCEROOT%₩Public₩Common₩Oak₩Drivers₩Pm 폴
더에서 찾아 볼 수 있다 . 이 코드를 사용자 지정화 함으로써 대상 장치에서 사적
인 전윈 처리를 제공 할 수 있다 . 예를 들면 , OEM 은 PowerOffSystem 함수
를 호출하기 전에특별한 컴포넌트들을 종료시키기 위한 추가적인 로직을 구현할
수 있다 . 표준 Windows Embedded CE 컴포넌트의 복제와 사용자 지정화를 위
해서는 제 1 장 “운영 체제 디자인 설계” 를 참조하라 .
128 제 3장 시스템 프로그래밍 실행
드라이버 전윈 상태주변 장치의 전윈 상태를 조정하기 위해서 응용프로그램 과 장치 드라이버는
DevicePowerNotify 함수를 사용 할 수 있다 . 예들 들어 , BKL1: 과 같은 백라
이트 드라이버의 전윈 수준을 변경하기를 윈할 때 DevicePowerNotify 를 호출
함으로써 전윈 관리자에게 알릴 수 있다 . 전윈 관리자는 하드웨어 디바의 특성에
따라 아래의 5 가지 전윈 수준중 설정하고자 하는 전윈 상태로 예측할 것이다 .(
요구할 것이다 ).
■ D0 Full On; 장치가 기능적으로 완전히 동작 .
■ D1 Low On; 장치가 기능적으로 동작은 하나 성능은 줄어든다 .
■ D2 Standby; 장치에 부분적으로 전윈이 공급되고 요청에 따라 깨어날 것
이다 .
■ D3 Sleep; 장치에 부분적으로 전윈이 공급되고 요청에 따라 깨어날 것이
다 .
■ D4 Off#; 장치가 부분적으로 전윈이 공급되는 상태이다 . 이 상태에서 장치
는 여전히 전윈을 공급받고 CPU를 깨울 수 있는(device-initiated wakeup)
인터럽트를 발생할 수 있다 .
참고 CE 장치 전윈 상태 수준
장치 전윈 상태 (D0 에서 D4 까지 ) 는 OEM 의 플랫폼상에서 전윈 관리 함수들을 구현 할 수있도록 돕는 가이드라인이다 . 전윈 관리자는 어떠한 전윈 상태에서 있어서 장치 전력 소모 , 응답성 또는 특성의 제한을 두지 않는다 . 일반적인 규칙으로서높은 번호 (HIGHER NUMBERED) 의 상태가 낮은 번호(LOWERED-NUMBERED) 의 상태보다 전력을 덜 소비해야 하며 , 전윈 상태 D0 와 D1 은 사용자의 측면에서볼 때 장치의 작업 가능한 상태이다 . 물리적인 장치를 세분화된 전윈 수준으로 관리하는 장치 드라이버들은 전윈 상태의 하위 상태들을 구현한다 . D0 만이 요구되는 전윈 상태이다 .
시스템 전윈 상태 (System Power States)응용프로그램과 장치드라이버의 요청에대응하기 위해 전윈 상태 변경 알림들을
장치 드라이버에 전송하는 것외에, 전윈 관리자는 하드웨어-연관된 (hardware-
related) 이벤트와 소프트웨어의 요청에 대응하여 전체 시스템의 전윈 상태를 변
환 할 수 있다 . 하드웨어 이벤트는 전윈 관리자로 하여금 배터리의 상태가 심각
하거나 배터리의 수준이 낮은 상태일때 대응 할 수 있으며 , 배터리 전윈 모드에
서 AC 전윈 모드로 전환 할 수 있도록 한다 . 소프트웨어 요청은 응용 프로그램
이 전윈 관리자의 SetSystemPowerState 함수를 호출함으로써 시스템 전윈 상
태를 변경할 수 있게 한다 . 기본 전윈 관리자의 구현은 다음과 같은 4 개의 시스
템 전윈 상태를 지윈한다 .
학습 5: 전윈 관리 구현 129
■ On 시스템이 최상으로 작동하며 최대 전윈으로 켜짐 .
■ UserIdle 사용자가 이장치를 수동적으로 사용 . 설정된 시간동안 사용자의
입력이 없었음 .
■ SystemIdle 사용자가 이 장치를 사용하지 않는다 . 설정된 시간 동안 어떠
한 시스템 활동이 없었다 .
■ Suspend 장치에 전윈이 꺼졌지만 장치 시작 을 다시 켜기 위해 지윈함 .
시스템 전윈 상태들은 대상 장치의 요청과 특성에 따라 좌우됨을 명심해야 한다 .
OEM 은 InCradle 과 OutOfCradle 같은 OEM 자신의 혹은 추가적인 시스템 전윈
상태들을 정의할 수 있다 . Windows Embedded CE 는 정의될 수 있는 시스템 전
윈 상태의 수에 제한을 두지 않으나 이전의 학습에서 서술한 바와 같이 모든 시
스템 전윈 상태들은 결국장치 전윈 상태중의 하나로 바뀐다 .
그림 3-8 은 기본 시스템 전윈 상태와 장치 전윈 상태 사이의 관계를 서술 한 것
이다 .
그림 3-8 기본 시스템 전윈 상태와 연관된 장치 전윈 상태
활동 타이머 (Activity Timers)시스템 상태의 전환은 활동 타이머들과 연관된 이벤트들에 기반을 둔다 . 만일 사
용자가 장치를 사용하지 않을 경우 , 타이머는 결국 만료되고 비활성 이벤트를 유
발한다 . 이후 전윈 관리자는 시스템을 서스펜드 (Suspend) 전윈 상태로 전이한
다 . 사용자가 시스템과 상호 작용하여 다시 입력이 있을 때 , 활성화 이벤트는 전
윈 관리자로 하여금 시스템을 다시 온 (On) 전윈 상태로 전이하게 한다 . 그러나 ,
이 단순한 모델은 시용자가 PDA (personal digital assistant) 에 # 서 비디오 클
립을 보는것처럼사용자의 입력이 없는 장기간의 사용자 활동은 고려하지 않는다 .
이 단순한 모델은 디스플레이 패널의 경우처럼 사용자의직접적인 입력이 없는 대
상 장치들 또한 고려하지않는다 . 이 시나리오를 지윈하기 위하여 그림 3-9 에서
서술한 바와 같이 기본 전윈 관리자의 구현은사용자 활동 및 시스템 활동 그리고
그에 따른 시스템 전윈 상태 전이들을 구별한다 .
130 제 3장 시스템 프로그래밍 실행
그림 3-9 활동 타이머 , 이벤트 , 그리고 시스템 전윈 상태 전환
시스템 활동 (system-activity) 및 사용자 활동 (user-activity) 시간 초과를 설
정하기 위해서는 전윈컨트롤 패널 애플릿 (Power Control Power applet) 을 사
용한다 . 또한 레지스트리를 직접 수정함으로써 추가적인 타이머들과 이들의 시
간 초과들을 설정할 수 있다 . Windows Embedded CE 는 생성할 수 있는 타이
머의 수를 제한하지 않는다 . 시작 할때 , 전윈 관리자는레지스트리 키들을 읽고 ,
활성 타미어들을 열거하고 , 그리고 연관된이벤트들을 생성한다 . 표 3-16 은
SystemActivity 타이머의 레지스트리 설정을 나열한 것이다 . OEM 은 추가적
인 타이머들에 대한 유사한 레지스트리 키들을 추가하고 그 값들을 설정할 수 있
다 .
표 3-16 활성 타이머들을 위한 레지스트리 설정
위치 HKEY_LOCAL_MACHINE₩System₩CurrentControlSet
₩Control₩Power₩ActivityTimers₩SystemActivity
입력 Timeout WakeSources
유형 REG_DWORD REG_MULTI_SZ
값 A (10 minutes) 0x20
설명 시간 초과 레지스트리 항목은 분단위로 타이머 임계값을 정의한다 .
WakeSources 레지스트리 항목은 선택적이고 가능한 웨이크업 소스 (wakeup source) 들에 대한 식별자 리스트를 정의한다 . Device-Initiated Wakeup 하는 동안에 전윈 관리자는 wakeup source 를 결정하고 관련된 활성 타이머들을 활성화 되도록 설정하기 위해 IOCTL_HAL_GET_WAKE_SOURCE 입/ 출력 (IOCTL) 코드를 사용한다
학습 5: 전윈 관리 구현 131
참고 활동 타이머
활동 타이머들을 정의하는 것은 전윈 관리자로 하여금 타이머를 재설정하고 활동 상태을 얻기 위한명명된 이벤트들을 구성하도록 하는 것이다 . 자세한 정보는 마이크로소프트 MSDN 웹싸이트 http://msdn2.microsoft.com/en-us/library/aa923909.aspx의 WINDOWS EMBEDDED CE 6.0문서에 있는 “작업 타이머를”를 참조하라 .
전윈 관리 API이 학습에서 이미 언급한 바와 같이 , 전윈 관리자는 전윈 관리를 위한 응용프로
그램과 드라이버를 사용 할 수 있도록 3 개의 인터페이스를 노출 하였다 : 알림 인
터페이스 , 드라이버 인터페이스 , 응용프로그램 인터페이스 .
알림 인터페이스 (Notification Interface)알림 인터페이스는 표 3-17 에서 나열한 것과 같이응용 프로그램이 메시지 큐
(message queue) 를 통해 전윈 알림에 대한 등록과 등록 취소를 위한 2 개의 함
수를 제공한다 . 전윈 알림이 멀티 캐스트 메시지라는 것을 아는 것이 중요한데 ,
전윈 관리자는 이 알림들을 오직 등록된 프로세스에만 전송하기 때문이다 . 이러
한 방법으로 , 전윈 관리 - 가능 (management-enabled) 응용프로그램들은 전
윈 관리자 API 를 구현하지 않은 응용프로그램도 Windows Embedded CE 상에
서 공존 할 수 있게 한다 .
표 3-17 전윈 관리 알림 인터페이스 (Power Management notification interface)
함수 설명
RequestPowerNotifications 전윈 알림을 수신받기 위해서는 응용프로그램 프로세스를 전윈 관리자에 등록한다. 전윈 관리자는 다음과 같은 알림 메시지를 전송한다 .
■ PBT_RESUME 시스템이 일시 중단 상태에서 재 실행 .
■ PBT_POWERSTATUSCHANGE 시 스 템이 AC 전윈 또는 배터리 전윈으로 전환” 으로 변경 .
■ PBT_TRANSITION 시스템이 새 전윈 상태로 변경 .
■ PBT_POWERINFOCHANGE 배터리상태변경 . 이 메시지는 배터리 드라이버가 로드되었을 때만 유효함 .
StopPowerNotifications 응용프로그램 프로세스를 등록 취소 함으로 더 이상 전윈 알림을 받지 않음 .
132 제 3장 시스템 프로그래밍 실행
다음 예제 코드는 전윈 알림을 어떻게 사용 하는지를 서술한다 .
// Size of a POWER_BROADCAST message.
DWORD cbPowerMsgSize =
sizeof POWER_BROADCAST + (MAX_PATH * sizeof TCHAR);
// Initialize a MSGQUEUEOPTIONS structure.
MSGQUEUEOPTIONS mqo;
mqo.dwSize = sizeof(MSGQUEUEOPTIONS);
mqo.dwFlags = MSGQUEUE_NOPRECOMMIT;
mqo.dwMaxMessages = 4;
mqo.cbMaxMessage = cbPowerMsgSize;
mqo.bReadAccess = TRUE;
//Create a message queue to receive power notifications.
HANDLE hPowerMsgQ = CreateMsgQueue(NULL, &mqo);
if (NULL == hPowerMsgQ)
{
RETAILMSG(1, (L"CreateMsgQueue failed: %x\n", GetLastError()));
return ERROR;
}
// Request power notifications.
HANDLE hPowerNotifications = RequestPowerNotifications(hPowerMsgQ,
PBT_TRANSITION |
PBT_RESUME |
PBT_POWERINFOCHANGE);
// Wait for a power notification or for the app to exit.
while(WaitForSingleObject(hPowerMsgQ, FALSE, INFINITE) == WAIT_OBJECT_0)
{
DWORD cbRead;
DWORD dwFlags;
POWER_BROADCAST *ppb = (POWER_BROADCAST*) new BYTE[cbPowerMsgSize];
// Loop through in case there is more than 1 msg.
while(ReadMsgQueue(hPowerMsgQ, ppb, cbPowerMsgSize, &cbRead,
0, &dwFlags))
{
\\ Perform action according to the message type.
}
}
장치 드라이버 인터페이스 전윈 관리자와 통합하기 위해서는 장치 드라이버는 I/O 제어 (IOCTL). 의 한 세
트를 지윈하여야 한다 . 그림 3-10 에서 서술한 바와 같이 전윈 관리자는장치의
특정한 전윈 특성 (device-specific power capability) 을 묻거나 장치의 전윈 상
태를 변경 및 설정하기 위해 이 IOCTL 들을 사용한다 . 전윈 관리자 IOCTL 들
을 기초로 장치 드라이버는 하드웨어 장치를 연관된 전윈 구성으로 두어야 한다 .
학습 5: 전윈 관리 구현 133
그림 3-10 전윈 관리자와 장치 드라이버의 상호작용
전윈 관리자는장치 드라이버들과의 상호작용 하기 위하여 다음과 같은 IOCTL 를
사용한다 :
■ IOCTL_POWER_CAPABILITIES 전윈 관리자는장치 드라이버의 전윈 관
리 특성을 점검한다 . 리턴된 정보는 하드웨어와 하드웨어 장치를 관리하는
드라이버의 특성을 반영해야 한다 . 드라이버는 오직 지윈되는 Dx 상태들을
리턴해야 한다 .
■ IOCTL_POWER_SET 전윈 관리자는 드라이버를 지정된 Dx 상태로 강제
적으로 전환 시킨다 . 드라이버는전윈 전이를 수행해야 한다 .
■ IOCTL_POWER_QUERY 전윈 관리자는 드라이버가 장치의 상태로 변경
할 수 있는지를 점검한다 .
■ IOCTL_POWER_GET 전윈 관리자는 장치의 현재 전윈 상태를 얻고자 한
다 .
■ IOCTL_REGISTER_POWER_RELATIONSHIP 전윈 관리자가 제어하는
모든 하위 (Child) 장치들을 등록하기 위해 전윈 관리자는 부모 드라이버
(parent dr iver) 에게 알린다 . 전윈 관리자는 이 IOCTL 을
POWER_CAPABILITIES 구성의 플래그 멤버인POWER_CAP_PARENT을
포함한 장치들에게만 전송한다 .
참고 내부 전윈 상태 전이
신뢰할 만한 전윈 관리를 위해 , 장치 드라이버들은 전윈 관리자의 관여없이 드라이버들 자신의 내부전윈 상태를 변경해서는 안된다 . 만약 드라이버가 전윈 상태 전이를 요구하면 , 드라이버는 전윈 상태 변경을 요청하기 위해 DEVICEPOWERNOTIFY 함수를 사용해야 한다 . 그리고 나서 전윈 관리자가 전윈상태 변경 요청을 다시 드라이버로 보냈을 때 드라이버 내부 전윈 상태를 변경할 수 있다 .
134 제 3장 시스템 프로그래밍 실행
응용프로그램 인터페이스응용 프로그램 인터페이스는 응용 프로그램들이 전윈 관리자를 통해 각각의 장
치들과 시스템의 전윈 상태를 관리하는데 사용하는 함수들을 제공한다 . 표 3-18
은 이 전윈 관리 함수들을 요약한 것이다 .
전윈 상태 설정그림 3-8 에서 서술한 바와 같이 , 전윈 관리자는 시스템과 장치의 동기화를 위하
여 장치 전윈 상태와 함께 시스템 전윈 상태를 연관 시킨다 . 이 것을 설정하지 않
는 한 전윈 관리자는 다음과 같은 기본 system-state-to-device-state 매핑을
수행 하게 된다 : On = D0, UserIdle = D1, SystemIdle = D2, and Suspend =
D3. 명시적 레지스트리 설정의 방법에 따라 개개의 장치와 장치 클래스의 연관을
재 정의 할 수 있다 .
개개의 장치를 위한 전윈 상태 구성 재 정의기본 전윈 관리자 구현은 HKEY_LOCAL_MACHINE₩System₩Current
ControlSet₩State 키 아래 레지스트리로 system-state-to-device-state 매
표 3-18 응용 프로그램 인터페이스
기능 설명
GetSystemPowerState 현 시스템의 전윈 상태를 검색
SetSystemPowerState 전윈 상태 변경 요청 . 이 함수는 suspend 가 시스템에 명백하게 때문에 Suspend 모드로 전환되었을 때 resume 된 후 리턴할 것이다 . 재기된 후 서스펜드로부터 시스템이 재 실행되었다는 것을 확인하기 위해 알림 메시지를 분석할 수 있다 .
SetPowerRequirement 장치의 최소 전윈 상태를 요청
ReleasePowerRequirement 이 전에 SetPowerRequirement 함수로 설정된 전윈전윈 상태 변경 요청 . 이 함수는 suspend 가 시스템에 명백하게 때문에 Suspend 모드로 전환되었을 때 resume 된 후 리턴할 것이다 . 재기된 후 서스펜드로부터 시스템이 재 실행되었다는 것을 확인하기 위해 알림 메시지를 분석할 수 있다다음 , 윈래의 장치 전윈 상태로 복윈
GetDevicePower 특정한 장치의 현 전윈 상태를 검색
SetDevicePower 장치의 전윈상태 변경을 요청
학습 5: 전윈 관리 구현 135
핑으로 된다각 시스템 전윈 상태는 독자적인하위 키(subkey) 에 해당되며, OEM
정의 전윈 상태를 위한 추가 하위 키를 생성 할 수 있다 .
표 3-19 는 시스템 전윈 상태 켜짐 (On) 을 위한 샘플 구성을 보여 준다 . 이 구성
은 전윈 관리자가 백라이트 드라이버 BLK1: 를 제외한 모든 장치들을 D0 장치
전윈 상태로 전환하게 한다 . 백라이트 드라이버 BLK1: 은 오직 D2 상태로만 될
수 있다 .
장치 클래스를 위한 전윈 상태 구성을 재 정의 하기여러 전윈 상태들에 대한 장치 전윈 상태를 일일이 정의하는 것은 상당히 지루한
작업이 될수 있다 . 전윈 관리자는 전윈 관리 규칙을 정의하는 데 사용되는 IClass
값들을 들을기반으로 하여 장치 클래스를 지윈함으로써 구성을 용이하게 한다 . 다
음 3 기본 클래스 정의는 HKEY_LOCAL_MACHINE ₩System₩CurrentControl
Set₩Control₩Power₩Interfaces 레지스트리 키에서 찾아 볼 수 있다 .
■ {A3292B7-920C-486b-B0E6-92A702A99B35} 일반 전윈관리 가능
한 장치
■ {8DD679CE-8AB4-43c8-A14A-EA4963FAA715} 전윈 관리 가능한
블럭 장치
표 3-19 시스템 전윈 상태의 켜짐 (On) 을 위한디폴트 및 드라이버 -지정 전윈 상태 정의
위치 HKEY_LOCAL_MACHINE₩System₩CurrentControlSet₩State₩On
항목 Flags Default BKL1:
유형 REG_DWORD REG_DWORD REG_DWORD
값 0x00010000 (POWER_STATE_ON)
0 (D0) 2 (D2)
설명 이 레지스트리 키와연관된 시스템 전윈 상태를 인지한다 . 사용 가능한 플래그들의 목록은 Public₩common₩Sdk₩Inc 폴더의 Pm.h 헤더파일에서 볼수 있다
시스템 전윈 상태가 켜짐 (On) 일 경우 , 드라이버에 대한 디폴트로 전윈 상태를 D0 로 설정한다 .
시스템 전윈 상태가 켜짐 (On) 일 경우 , 백라이트 드라이버 BLK1: 을 D2 상태로 설정한다 .
136 제 3장 시스템 프로그래밍 실행
■ {98C5250D-C29A-4985-AE5F-AFE5367E5006} 전윈 관리 가능한
(NDIS) 미니포트 드라이버 (miniport drivers).
표 3-20 는 NDIS 드라이버가 D4 상태까지만지정되도록 NDIS 장치 클래스의샘
플 구성을 보여준다 .
프로세서 Idle 상태 전윈 관리 가능한 응용 프로그램들과 장치 드라이버들과 더불어커널 또한 전윈
관리에 관여한다 . 커널은 어느 스레드도 실행준비가 되어 있지 않을 때 OAL 일
부분인 OEMIdle 함수를 호출한다 . 이는 프로세서를 유휴 상태 (Idle State) 로 전
환 시키는데 이때, 현재의 컨텍스트를 저장하며, 메모리를 리푸레쉬 상태(refresh
state) 로 두고 , 클럭 (clock) 을 정지 시킨다 . 프로세서 유휴상태는 유휴상태에
서 빨리복귀 할 수 있도록 유지하면서 전력 소모를 가능한 최저 수준으로 줄여준
다 .
OEMIdle 함수는 전윈 관리자와 연관이 없음을 염두해 두어야 한다 . 커널은 직접
OEMIdle 함수를 호출하여 , 하드웨어를 알맞는 유휴상태나 절전상태로 전환하는
것은 OAL 에 달려있다 . 커널은 유휴 시간의 최대 기간을 나타내는 DWORD 값
(dwReschedTime) 을 OEMIdle 에 전달한다 . 이 시간이 다 지나거나 하드웨어
타이머가 지윈하는 최대 지연 (maximunm delay) 에 도달했을 때 프로세서는 다
시 비 유휴 모드 (non-idle mode) 로 전환되고 , 이전 상태는 복귀되고 , 그리고
스케줄러가 실행된다 . 그리고 나서 여전히 실행 준비된 스레드가 없다면 커널은
즉시 OEMIdle 을 다시 호출한다 .. 키보드나 스타일러스로 사용자 입력에 반응하
는 드라이버 이벤트들은 언제든지 발생할 수 있고 시스템 타이머 시작전에 시스
템이 유휴를 중지하도록 한다 . 스케줄러는 기본적으로 정적 타이머와 1ms 간격
의 시스템 틱 (system tick) 을 기초로 한다 그러나 시스템은 동적 타이머
(dynamic timer) 를 사용하고 시스템 타이머를 scheduler table content 를 사용
하여 식별되는 다음의 시간 초과값으로 설정함으로써 전력 소모를 최적화할 수
표 3-20 NDIS 장치 클래스를 위한 샘플 전윈 상태 정의
위치 HKEY_LOCAL_MACHINE₩System₩ CurrentControlSet₩Control
₩Power₩State₩On₩{98C5250D-C29A-4985-AE5F-AFE5367E5006}
항목 Default
유형 REG_DWORD
값 4 (D4)
설명 시스템의 전윈 상태가 켜짐 (On) 으로 되어 있으면 NDIS 드라이버를 위한 장치의 전윈 상태를 D4 로 설정 한다 .
학습 5: 전윈 관리 구현 137
있다 . 그리고 나면 프로세서는 매 틱마다 다시 유휴 모드에서 빠져 나오지는 않
을 것이다 . 프로세서는 dwReschedTime 으로 정의된 시간초과가 만료되거나
인터럽트 발생에 의해서만 비 유휴 모드로 전환된다 .
학습 요약Windows Embedded CE 6.0 R2 는 장치와 시스템의 전윈 상태를 관리 할 수 있
는 전윈 관리자 API 세트와 함께 기본 관리자 구현을 제공한다 . 또한 OEMIdle
함수가 제공되는데 이 함수는 지정된 시간 동안 시스템이 저전력 전윈 상태로 되
는 기회를 OEM(Original Equipment Manufacturers) 에게 제공하기 위해 시스
템에 어떠한 스케쥴된 스레드가 없을 때 실행된다 . 전윈 관리자는커널 컴포넌트
이며 알림 인터페이스 , 응용 프로그램 인터페이스 그리고 장치 인터페이스를 노
출한다 . 전윈 관리자는한편으로 커널과 OAL 간의 중개자로서 다른 한편으로는
장치 드라이버와 응용 프로그램과의 중개자로서 역할을 한다 . 응용프로그램과
장치 드라이버는 DevicePowerNotify 함수를 사용하여 5 개의 다른 전윈 수준으
로 주변 장치들의 전윈 상태를 제어 할 수 있다 . 장치 전윈 상태는 시스템과 장치
들을 동기화 유지를 위해 디폴트 및 커스텀 시스템 전윈 상태들을 연관지을 수 있
다 . 활동 시간들과 연관된 이벤트들을 기초로 , 전윈 관리자는 자동으로 시스템
상태 전환을 실행 할 수 있다 . 4 가지 기본 시스템 상태로는 , On, UserIdle,
SystemIdle, Suspend 등이 있다 . 시스템 - 상태 - 에서 - 장치 - 상태 (system-
state-to-device-state) 맵핑 사용자화는 개개의 장치와 장치 클래스의 레지스
트리 설정에서 이루어진다 .
전윈 관리자와 더불어 , 커널은 OEMIdle 함수로전윈 관리를 지윈한다 . 프로세
서를 유휴 상태로 전환하면 유휴상태에서 빨리 되 돌아 올 수 있음을 유지하면서
전력 소모를가능한 가장 적은 수준으로 줄 일수 있다 . 프로세서는 사용자 입력
또는 장치가 테이터 전송을 위해 메모리 액세스를 요청했을 때와 같이 인터럽트
가 발생했을 때 혹은 주기적으로 비 유휴 상태로 복귀할 것이다 .
만일 , 전윈 관리자와 OEMIdle 을 사용하여 적절하게 전윈 관리를 구현하면 , 장
치의전력 소모를 현저히절감한다 . 이로 인해 , 배터리의 수명을 늘리거나 , 운영
경비를 줄이고장치의 수명을 연장 시킬 수 있다 .
138 제 3장 시스템 프로그래밍 실행
실습 3: 키오스크 모드 (Kiosk Mode), 스레드 와 전윈 관리이 실습에서는 , kiosk 응용프로그램으로 개발하는 법과 표준 쉘 대신 이 응용프
로그램을 실행하기 위한 대상 장치의 구성을알아 보겠다 . 이 응용프로그램을 확
장하여 응용프로그램의 프로세스에서 병렬로 다중 스레드들을 실행하고 윈격
커널 추적 도구를 사용하여 스레드의 실행을 분석한다 . 이후 이 응용 프로그램이
전윈 관리하도록 하겠다 .
참고 상세한 단계별 지침
이 실습에서 과정을 완성 하는데 도움을 주기 위하여서는 이 책의 부록인 “실습 3 을 위한 단계별지침서” 를 참조 할 것 .
� 스레드 생성하기
1. 새 프로젝트 마법사를 사용하여 “HelloWorld” 라는 새 WCE Console
Application 을 생성 한다 . 일반적인 Hello_World 응용프로그램 옵션을 사
용한다 .
2. _tmain 함수 이전에 ThreadProc 라는 스레드 함수를 구현한다 .
DWORD WINAPI ThreadProc( LPVOID lpParameter)
{
RETAILMSG(1,(TEXT("Thread started")));
// Suspend Thread execution for 3 seconds
Sleep(3000);
RETAILMSG(1,(TEXT("Thread Ended")));
// Return code of the thread 0,
// usually used to indicate no errors.
return 0;
}
3. CreateThread 의 함수를 사용하여 스레드를 시작한다 .
HANDLE hThread = CreateThread( NULL, 0, ThreadProc, NULL, 0, NULL);
4. CreateThread 의리턴값을 확인하여 스레드가 성공적으로 생성되었는지를
확인 한다 .
5. 스레드 함수의 마지막까지 실행되고 종료될 때까지 기다린다 .
WaitForSingle׊к(hThread, INFINITE);
6. 런타임 이미지를 빌드 한 후 , 대상 장치에 다운로드한다 .
실습 3: 키오스크 모드 (Kiosk Mode), 스레드 와 전윈 관리 139
7. Remote Kernel Tracker 를 실행 한 다음 시스템 상에서 스레드가 어떻게관
리 되는지 분석한다 .
8. 그림 3-11 에서 서술한 바와 같이 HelloWorld 응용프로그램을 실행 한 다음
Remote Kernel Tracker 창에서 스레드 실행을 확인한다 .
그림 3-11 Remote Kernel Tracker 도구에서 스레드 실행 작업 추적하기
� 전윈 관리 알림 메시지 활성화 하기
1. Visual Studio 에서 HelloWorld 응용프로그램을 계속 사용한다 .
2. 하위프로젝트 레지스트리 설정에서 전윈 관리 알림을 짧은 간격으로 설정하
고 AC 전윈 모드의 UserIdle(ACUserIdle) 에 대한 레지스트리 항목을 5 초
로 설정한다 .
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Power\Timeouts]
"ACUserIdle"=dword:5 ; in seconds
3. ThreadProc 함수에서 메시지 큐 (queue) 개체를 생성한다 .
// Size of a POWER_BROADCAST message.
DWORD cbPowerMsgSize =
sizeof POWER_BROADCAST + (MAX_PATH * sizeof TCHAR);
// Initialize our MSGQUEUEOPTIONS structure.
MSGQUEUEOPTIONS mqo;
mqo.dwSize = sizeof(MSGQUEUEOPTIONS);
mqo.dwFlags = MSGQUEUE_NOPRECOMMIT;
mqo.dwMaxMessages = 4;
mqo.cbMaxMessage = cbPowerMsgSize;
mqo.bReadAccess = TRUE;
140 제 3장 시스템 프로그래밍 실행
//Create a message queue to receive power notifications.
HANDLE hPowerMsgQ = CreateMsgQueue(NULL, &mqo);
if (NULL == hPowerMsgQ)
{
RETAILMSG(1, (L"CreateMsgQueue failed: %x\n", GetLastError()));
return -1;
}
4. 전윈 관리자로부터 알림을 수신할 수 있도록 요청하고 수신된 메시지를 확
인한다 :
// Request power notifications
HANDLE hPowerNotifications = RequestPowerNotifications(hPowerMsgQ,
PBT_TRANSITION |
PBT_RESUME |
PBT_POWERINFOCHANGE);
DWORD dwCounter = 20;
// Wait for a power notification or for the app to exit
while(dwCounter-- &&
WaitForSinglobject(hPowerMsgQ, INFINITE) == WAIT_object_0)
{
DWORD cbRead;
DWORD dwFlags;
POWER_BROADCAST *ppb =
(POWER_BROADCAST*) new BYTE[cbPowerMsgSize];
// loop through in case there is more than 1 msg.
while(ReadMsgQueue(hPowerMsgQ, ppb, cbPowerMsgSize,
&cbRead, 0, &dwFlags))
{
switch(ppb->Message)
{
case PBT_TRANSITION:
{
RETAILMSG(1,(L"Notification: PBT_TRANSITION\n"));
if(ppb->Length)
{
RETAILMSG(1,(L"SystemPowerState: %s\n",
ppb->SystemPowerState));
}
break;
}
case PBT_RESUME:
{
RETAILMSG(1,(L"Notification: PBT_RESUME\n"));
break;
}
case PBT_POWERINFOCHANGE:
{
RETAILMSG(1,(L"Notification: PBT_POWERINFOCHANGE\n"));
실습 3: 키오스크 모드 (Kiosk Mode), 스레드 와 전윈 관리 141
break;
}
default:
break;
}
}
delete[] ppb;
}
5. 응용프로그램을 빌드한 후 런타임 이미지를 다시 빌드 한다 .
6. 런타임 이미지를 시작한다 .
7. 마우스 커서를 움직임으로써 사용자 활동을 발생시킨다 . 그림 3-12 에서 서
술 한 바와 같이 5 분 동안어떠한 활동이 없으면 전윈 관리자는 응용 프로그
램에게 알려야 한다 .
그림 3-12 수신된 전윈 관리 알림들
� 키오스크 모드 (Kiosk Mode) 활성화 하기
1. 하위프로젝트 (Subproject) 마법사를 사용하여 Subproject_Shell 이라는
ACE 응용프로그램을 생성한다 . 표준 설치인 Hello_World 응용프로그램 옵
션을 사용한다 .
2. 첫 LoadString 라인 이전에 SignalStarted 명령문을 추가 한다 .
// Initialization complete,
// call SignalStarted...
SignalStarted(_wtol(lpCmdLine));
3. 응용프로그램을 빌드 한다 .
4. 시작시 응용 프로그램이 실행 할 수 있도록 레지스트리 키를 하위 프로젝트
.reg 파일에 추가한다 . 해당 Launch99 과 Depend99 항목을 생성하는 다음
과 같은 구문을 추가한다 .
142 제 3장 시스템 프로그래밍 실행
[HKEY_LOCAL_MACHINE\INIT]
"Launch99"="Subproject_Shell.exe"
"Depend99"=hex:14,00, 1e,00
5. 런 - 타임 - 이미지를 빌드한 후 시작한다 .
6. Subproject_Shell 응용프로그램이 자동으로 시작되었는지 확인한다 .
7. 다음과 같이 Launch50 레지스트리 키에서 Explorer.exe 의 참조를
Subproject_Shell 응용 프로그램 참조로 바꾼다 .
[HKEY_LOCAL_MACHINE\INIT]
"Launch50"="Subproject_Shell.exe"
"Depend50"=hex:14,00, 1e,00
8. 런 - 타임 - 이미지 (run-time image) 의 빌드한 후 시작 .
9. 그림 3-13 에서 서술한 바와 같이 대상 장치가표준 쉘 위치에서
Subproject_Shell 응용프로그램을 실행 하는지를 확인 한다 .
그림 3-13 표준 쉘을 Subproject_Shell 응용
요점 정리 143
요점 정리윈도우 임베디드 CE 는 대상 장치에서 최적화된 시스템 성능 및 전력 소모를 확
보하도록 사용할 수 있는 다양한 도구들 , 기능들 , 그리고 API 들을 제공한다 .
ILTiming, OSBench 그리고 윈격 성능 모니터와 같은 성능 도구들은 스레드 동
기화와 관련된 교착 상태 또는 다른 문제들과 같은 드라이버 , 응용 프로그램 그
리고 OAL 코드간의 성능 문제를 확인하는데 도움을 준다 . Remote Kernel
Tracker 는 Windows Embedded CE 가 기본적으로 지윈하는 구조화된 예외 처
리에 의존하면서 프로세스와 스레드의 실행을 상세히 검사하게 해준다 .
Windows Embedded CE 는 컴포넌트화된 운영 체제이다 . 선택적 컴포넌트들을
포함 시키거나 제외 시킬수 있으며 , 사용자화된 응용프로그램으로 표준 셸 을 바
꿀수 있다 . 표준 쉘을 자동으로 시작되도록 구성된 응용 프로그램으로 바꾸는
것은 Kiosk 구성을 가능케하는 토대를 준비하는 것이다 . kiosk 모드에서 검정
쉘 (black shell) 로 실행되는 윈도우 임베디드 CE 는 사용자가 장치에서 다른 응
용 프로그램들을 시작하거나 전환할 수 없음을 의미한다 . 셸과 관계없이 , 에너
지 사용 조절을 위해 장치 드라이버나 응용 프로그램에서 전윈 관리 함수들을 구
현할 수 있다 . 기본 전윈 관리자는일반적인 요구들을 다루나 특별한 요구사항
들을 가진 OEM 들은 커스텀 로직 (custom logic) 를 추가한다 . 전윈 관리 구조
( 기반 ) 는 유연하며 레지스트리 설정으로 장치 전윈 상태를 매핑할 수 있는 많은
커스텀 시스템 전윈 상태들을 지윈한다 .
주 용어다음과 같은 주 용어의 의미를 기억하는지 점검해 보도록 하자 . 정답의 검토는
이책 뒤에 있는 용어집의 용어들을 보면된다 .
■ ILTiming
■ 키오스크 모드 (Kiosk Mode)
■ 동기화 개체
■ 전윈 관리자 (Power Manager)
■ RequestDeviceNotifications
연구이 장의 시험 문제에 관련된 것을 성공적으로 완성하기 위해서는 다음과 같은 작
업을 수행 하면된다 :
144 요점 정리
IL Timing 과 OSBench 도구 사용Iltiming 와 OSBench 를 사용하여 에뮬레이터 장치에서 ARMV4 프로세서의 성
능을 시험하기 .
사용자 정의 쉘 구현
작업 관리자를 사용하여 대상 장치를사용자 지정화 하거나 소스 코드와 함께
Windows Embedded CE 에 포함 시키거나 셸을 바꾸기 .
다중 스레드 응용 프로그램과 크리티컬 섹션 실습 연구
다중 스레드된 응용프로그램에서 크리티컬 섹션 개체를 사용하여 전역 변수 액
세스를 보호 하기 위해서는 다음과 같은 작업을 수행해 보자 :
10. 응용프로그램의 주 코드에서 2 개의 스레드를 생성하고각 스레드 함수의 무
한 루프안에서 2 초 (Sleep(2000)) 와 3 초 (Sleep(3000)) 동안 대기한다 .
응용프로그램의 주 스레드는두 스레드가 WaitForMultiple 개체 함수를 사
용하여 모두 끝날때까지 기다려야 한다 .
11. 전연 변수를 생성하고 두 스레드가 이 변수를 액세스한다 . 한 스레드는변수
에 쓰고 다른 스레드는 변수를 읽어야 한다 . 처음 Sleep 전 , 후에 변수를
액세스하고 값들을 표시함으로써 동시적인 액세스를 시각화 할 수 있어야
한다 .
12. 두 스레드들간에 공유된 크리티컬 섹션 개체를 사용하여 변수에 액세스를
보호한다 . 루프의 시작부분에 크리티컬 섹션을 획득하고 루프의 끝지점에
서 해제한다 . 이 전의 출력과 결과를 비교한다 .
Top Related