이것저것/Windows CE

윈도우CE 디바이스 드라이버에 관한 12가지 이야기

우담바라 2009. 11. 26. 11:25

[펌] 윈도우CE 디바이스 드라이버에 관한 12가지 이야기 - 라영호
 
[지디넷코리아]드디어 디바이스 드라이버를 살펴보는 시간이 왔다. 사실 지금까지 오는 과정도 많은 기술적인 부분을 생략하였기 때문에 좀 찜찜한 느낌이 드는 것은 어쩔 수 없다. 모든 내용을 다루기에는 제약이 있기 때문이다.

하지만 본 ZDNet 연재를 본 독자들은 조금이나마 CE에 대한 새로운 시각이 생겼을 것이다. CE에 대한 기술적인 내용을 세세히 아는 것도 중요하다. 하지만 기술적인 사항은 스스로 공부를 해도 충분하다. 따라서 본 연재에서는 스스로 공부하면서 얻을 수 없는 경험이나 사례들을 나누고 싶다. 이를 통해 보다 좋은 제품을 만들 수 있는 바탕이 되기를 바란다.

1. 디바이스 드라이버(Device Driver)란?

'CE를 탑재한 제품 개발에 있어 디바이스 드라이버는 어떻게 보면 개발 작업의 많은 부분을 차지하는 부분이다.'

네비게이션 시스템을 개발한다고 가정해 보자.
-화면 표시를 위한 LCD 드라이버가 있어야 하며,
-소리 출력을 위한 사운드 드라이버,
-GPS 모듈과 연결을 하여 위치 추적을 위한 GPS 드라이버(시리얼 드라이버라는 것이 옳지만 문맥상 GPS 드라이버라고 한다)등 다양한 종류의 디바이스 드라이버가 있다.

카메라, 오디오, 디스플레이, CDMA 모듈과 같은 통신 장치와 연결 및 동작시키는 복잡한 드라이버에서부터 장치에 있는 LED를 키고 끄는 기능을 하는 간단한 기능의 LED 디바이스 드라이버도 있다. CE 운영체제가 마이크로프로세서를 동작시키기 위해 존재한다면 디바이스 드라이버는 마이크로프로세서와 연결된 장치들을 다루는 소프트웨어라고 생각하면 된다.

CE 이전에도 PC에 USB 랜 카드나 비디오 카드를 변경 했을 때 디바이스 드라이버를 설치하였던 경험이 있을 것이다. 인터넷이나 첨부된 CD에서 장치용 디바이스 드라이버를 매뉴얼에서 알려 준 것처럼 설치하면 되는 것이다. 일반 PC용 디바이스 드라이버는 주변 장치 제조업체에서 제공해 준다는 것은 당연히 알고 있는 사실이다. 이와 다르게 CE에서는 CE를 개발하는 업체에서 만드는 장치에 맞게 만들어야 한다는 차이점이 있는 것이다.

물론, 어느 정도의 소스코드는 제공한다. PC와는 다르게 독립된 제품이 아닌 칩 단위로 판매되기 때문에 디바이스 드라이버도 대표되는 제품에 대한 소스코드(대부분의 업체가 참고용 디바이스 드라이버 소스나 실행 파일를 제공하기는 하지만 제공 안 되는 경우도 많이 있음)나 참고 드라이버가 형태로 제공이 되고, 이 드라이버 소스를 개발하는 제품이 맞게 포팅 하는 작업을 거쳐 해당 디바이스 드라이버로 만들어 지는 것이다. 따라서 제조업체에서 제공해주는 드라이버를 설치하는 개념에서 개발하는 장치의 드라이버를 만들어야 한다는 것으로 바꿔야 하는 것이다. <그림1>은 임베디드 시스템에서 드라이버의 역할을 설명해 주는 그림이다.


<그림1>디바이스 드라이버

2. CE 그리고 디바이스 드라이버

<표 1>은 디바이스 드라이버의 구조 및 기능을 분류한 것이다. 표에 있는 것처럼 구분하기 모호한 디바이스 드라이버도 있다. 대부분의 디바이스 드라이버는 표에서 정의한 분류에 속한다고 생각하면 된다.


<표1>디바이스 드라이버의 구조 및 기능

마이크로프로세서에 부착된 장치만큼이나 디바이스 드라이버도 많다. USB 드라이버로 분류되어 USb를 통한 통신을 하지만 실제 동작은 시리얼 통신이나 USB를 통한 저장소를 관리하는 에뮬레이션하는 복잡한 기능의 드라이버도 많아지는 추세다. 그 만큼 장치의 복잡도가 증가하고 있기 때문이다. 디바이스 드라이버의 주목적은 'CE가 설계한 디바이스 드라이버 구조에 맞게 부착된 장치를 효율적으로 사용하게 하는데 있다.'

PC와 통신을 하는 USB 디바이스 드라이버라면
-PC 와의 데이터 전송 속도가 빨라야 할 것이며,
-PC에 연결 했을 때는 USB 장치로써 제대로 인식이 되어야 하면,
-PC에서 연결 해제 시에는 안정적으로 PC의 장치 목록에서 제거 되어야 한다.

이와 같이 디바이스 드라이버로써 갖춰야 할 기본 동작이 잘 되어야 한다.

3. MDD/PDD란?

MDD/PDD 형태의 디바이스 드라이버는 디스플레이 드라이버나 시리얼 드라이버와 같은 복잡한 것을 위해 태어났다. 디바이스 드라이버의 상위 레벨의 복잡한 부분은 사에서 제공한 MDD라는 형태의 라이브러리를 이용하고 하드웨어 설정에 관련된 PDD 부분만 수정해 개발하는 방식이다.

<그림2>는 대표적인 MDD/PDD 형태의 디바이스 드라이버인 시리얼 드라이버의 구조를 나타낸 것이다. 녹색 부분은 가 제공하는 MDD부분이고, 노란색 부분은 하드웨어에 맞추어 수정해야 하는 PDD 부분을 표시한다.

-MDD : Model Device Driver, 가 제공하는 드라이버 라이브러리
-PDD : Platform-Dependent Driver, 하드웨어따라 수정해야 하는 드라이버 부분


<그림2>시리얼 드라이버 구조 (출처: http://wecom.dstcorp.com/images/zdnet_img_64.gif)

4. 디바이스 드라이버 구분해보기

위의 <표1>을 다시 참고해보자. 이는 디바이스의 특성에 맞춘 분류로도 볼 수 있다. 디바이스 드라이버 종류는 그 장치만큼이나 많이 있고 다양하다. 체계적인 분류를 통해 디바이스 드라이버가 어떻게 동작할 것인가 예상해 보는 것도 좋은 방법이다.

5. 알아야 할 것들, 몰라야 할 것들

사실 디바이스 드라이버를 개발한다고 하면 장치 자체에 대한 지식뿐만 아니라 CE 운영체제에서 어떻게 디바이스 드라이버가 동작하고 어떻게 구성해야 하는지도 알아야 한다.

이후에 디바이스 드라이버를 동작시키기 위한 CE 운영체제를 어떻게 설정하고 인터럽트는 어떻게 처리하는지 알면 디바이스 드라이버에 대한 기초적인 개념을 잡을 수 있다. CE 운영체제가 임베디드용 중요한 운영체제로 인식되고 있는 지금은 참조용 디바이스 드라이버 소스를 제공하고 있거나 없다면 참고할 수 있는 자료를 구할 수 있다.

오디오나 카메라 드라이버와 같이 복잡한 것의 경우 최소 2개월 이상의 개발 기간이 소요되는 드라이버도 있고 간단히 수일 내로 작성할 수 있는 드라이버도 있다.

단 주의할 점은 디바이스 드라이버는 같이 동작하는 운영체제에 맞춰 최적화 작업이 우선돼야 한다는 것이다.

대부분 각 드라이버마다 담당자가 있고 개발 능력이나 방법의 차이가 있기 때문에 어떻게 융화 시켜 안정적인 시스템을 만드는가가 중요한 문제일 것이다. 이 문제에 대한 정답은 될 수 있으면 빠른 시간 내에 통합 작업을 하여 지속적인 테스트를 하는 수밖에 없다고 본다.

'CE 운영체제를 이용한 개발은 전체 통합, 이미지 빌드 & 테스트'라는 것을 항상 명심하기 바란다.

6. 디바이스 드라이버 제작 단계

디바이스 드라이버는 아래 <표 2>와 같이 간략하게 개발 단계를 정리할 수 있다. CE용 디바이스 드라이버는 초기 운영체제로부터 이어온 인터럽트를 이용한 처리 방법을 고수한다. 인터럽트를 이용하여 외부 장치에 대한 요구 사항, 데이터 전송 등을 효과적으로 처리한다.

인터럽트 처리를 위해선 CE의 커널 영역에서 전달된 인터럽트를 디바이스 드라이버에서 받아 처리하는 루틴을 디바이스 드라이버 내 쓰레드(Thread) 형태로 구현하여 처리할 수 있도록 해야 한다.

운영체제를 담당자는 OAL 포팅 시 인터럽트에 대한 정보를 먼저 수집하고 인터럽트를 다른 드라이버에서 사용할 수 있도록 SYSINTR_KEY_INT 와 같은 형태로 등록하여 그 처리 루틴을 올려야 한다. 이후 개발자는 이 인터럽트에 대한 처리 루틴을 디바이스 드라이버에 구현하게 된다.

디바이스 드라이버 내에서의 인터럽트 처리 방법에 대해 이해했다면 어느 정도 디바이스 드라이버 구현에 대한 개념을 알았다고 볼 수 있다.


<표2>디바이스 드라이버 제작 단계

7. 디바이스 드라이버의 등록은?

CE용 디바이스 드라이버는 대부분 운영체제에 포함되어 읽히는 형태이다. .REG 파일과 .BIB 파일에 디바이스 드라이버에 대한 정보를 등록해 두면 부팅 시 해당 디바이스 드라이버를 로드하게 된다.

디바이스 드라이버는 XXX_ 형태로 함수를 구성한다. LED를 제어하는 드라이버라면 "LED_" 형태의 구성 함수 이름을 가진다. 이 디바이스 드라이버가 운영체제에 의해 로드된 후에는 "LED0:"와 같은 고유 ID를 통해 디바이스 드라이버에 대한 관리 및 제어를 할 수 있다.

CE에서 디바이스 드라이버는 DLL 형태의 실행 파일이다. PC에서 DLL을 만드는 것처럼 CE에서도 .DEF 파일을 만들어 DLL을 생성하여야 한다. 개발된 드라이버는 레지스터리에 등록하여서 운영체제가 부팅 작업 도중 로드될 수 있도록 해야 한다.

다음은 레지스터리에 등록된 드라이버의 예시다. wavedev.dll이라는 디바이스 드라이버는 WAV라는 디바이스 드라이버관리용 Prefix를 가지며, Order와 같은 레지스터리 설정 값에 의해 CE에 의해 언제 로딩 될지 지정할 수 있다.

[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\WaveDev\]
"Prefix"="WAV"
"Dll"="wavedev.dll"
"Index"=dword:1
"Order"=dword:0
"Priority256"=dword:95
"Sysintr"=dword:19
"IClass"="{A32942B7-920C-486b-B0E6-92A702A99B35}" ; power managed device

8. 디바이스 드라이버와 데이터시트?

디바이스 드라이버를 제대로 만들기 위해서는 위의 <표2>와 같은 순서로 제작하면 된다. '생각보다 간단하군!' 하고 생각하면 오산이다. 디바이스 드라이버의 구조나 개발 자체는 사실 어려운 문제는 아니다. 어려운 문제는 마이크로프로세서와 디바이스(오디오의 경우 코덱 칩)와의 인터페이스를 제대로 설정하고, 디바이스의 On/Off, 초기화, 동작을 위한 명령을 잘 전달할 것인가 하는데 있다.

디바이스 자체에 대한 정보는 샘플로 제공하는 소스나 데이터 시트가 전부기 때문에 실제 장치를 자유자제로 프로그래밍 하기가 쉽지는 않을 것이다. 필자는 펌웨어라는 개념의 마이크로프로세서 프로그래밍을 먼저 시작했었다. 운영체제라고 하기는 뭐한 마이크로프로세서에서 동작하는 프로그램을 작성하는 개발이다.

main() 함수 속에 순차적으로 프로세서 동작 시에 필요한 작업들에 대해 프로그래밍 해야 했다. 디바이스 드라이버라는 개념도 운영체제라는 개념도 없는 상태였기 때문에 PC에서 프로그래밍 하듯이 작성을 하면 되었다.

사실 마이크로프로세서에 연결된 디바이스도 지금처럼 복잡하지 않기 때문에 명령을 위한 레지스터만 잘 이해하고 프로그래밍을 하면 됐다. 쉽게 보이는 과정이지만 마이크로프로세서의 하드웨어, 프로세서 및 장치간의 관계를 정확히 이해했기 때문에 가능했던 작업이다.

이후에 CE 운영체제에서 디바이스 드라이버를 개발을 하게 되었다. 당시에는 CE라는 운영체제 자체에 대한 개념이 부족했었다. 실제 드라이버 자체를 코딩하는 일이 쉬웠던 것과는 대조적인 일이다. 물론, 이후 CE 구조 및 동작 방식을 이해한 후에는 드라이버 작성도 어렵지 않았다.

이와 비교해서 지금의 디바이스 드라이버 개발자들은 필자와 같은 펌웨어(혹은 로우레벨) 단계의 개발 경험이 없기 때문에 CE 운영체제에서 드라이버 작성은 금방 하는데 디바이스 자체를 다루는 데는 부족한 점을 보여준다.

PC상에서 윈도 프로그래밍에 대한 경험이 많고 CE에 대한 구조적인 이해는 빠르지만 정작 디바이스를 다룰 때는 어려움을 호소하는 것을 종종 보게 된다. 사실 데이터시트만 가지고 디바이스 드라이버를 작성할 수 있는 엔지니어가 적다는 것이다.

하지만 다행히도 드라이버 소스나 인터넷상에서 찾을 수 있는 정보가 많기 때문에 이런 어려움을 충분히 극복할 수 있다. 임베디드 시스템을 다루는 디바이스 드라이버 엔지니어에게는 하드웨어에 지식이 필수이다.

9. 디바이스 드라이버 개발에서 주의 할 점

CE 디바이스 드라이버 개발 시 "\PUBLIC\COMMON\OAK\DRIVERS"라는 경로명은 반드시 알아야 한다. DN도 좋고 매뉴얼도 좋지만 소스를 참조한다는 것은 개발의 가장 중요한 기본이다.

분야별 다양한 종류의 소스가 있기 때문에 필요한 디바이스 드라이버 소스를 찾아서 거기서부터 개발의 시작으로 생각하면 된다. 소스가 생각보다 많기 때문에 일일이 살펴보는 것은 사실상 불가능한 일이다. 하지만 소스에 대한 세부적인 설명이 없기 때문에 DN에서 소스에 대한 대략적인 내용을 파악한 후 소스를 찾는 노하우가 필요하다.

디바이스 드라이버는 기술적으로 난이도가 있는 분야 중 하나다. CE라는 운영체제가 원하는 기술적인 스펙을 따르게 구현해야 하는 점이 첫 번째 어려움이며, 드라이버는 운영체제에 속해 동작해야 한다는 점이 또 하나의 어려움이다.

단독으로 동작하는 소프트웨어는 개발하기 쉽다. 하지만 운영체제 밑에서 운영체제의 제어를 받으며 다른 디바이스 드라이버와 조화로움을 이루면서 동작하게 구현하려면 고민을 하면서 개발을 진행 해 나가야 한다.

10. 디바이스 드라이버와 가상메모리?

디바이스 드라이버를 처음 개발 할 때 초보자들이 헷갈리는 점 중의 하나를 꼽아 본다면 가상 주소(Virtual Address)에 관련된 사항이다.

마이크로프로세서나 주변장치의 레지스터를 접근할 때 VirtualAlloc()이나 VirtualCopy()와 같은 함수를 사용하여 가상 메모리를 할당해서 사용해서 제어 할 수 있다. 그 이유는 드라이버는 운영체제가 관리하는 주소 체계 안에서 동작해야 해야 한다. 모든 주소는 마이크로프로세서가 제공하는 실제 주소가 아닌 CE가 관리하는 가상 주소로 변환되기 때문이다.

따라서 원래 마이크로프로세서에서 제공하는 레지스터의 주소가 아닌 CE가 관리하는 가상 주소를 통해 제어할 수 있는 것이다. 이러한 가상 주소의 개념을 드라이버 처음 개발 시 이해하고 있어야 한다.

11. 디바이스 드라이버는 하드웨어를 제어하는 것이다.

디바이스 드라이버의 목적은 주변 장치를 제어하는 것이다. LCD 드라이버는 LCD Controller와 TFT LCD 모듈을 제어하는 것이다. 제어를 하기 위해서는 우선 LCD Controller와 어떻게 통신을 하는지 우선 알아야 한다.

대부분의 주변 장치들이 메모리와 같이 주소로 지정할 수 있는 메모리 주소 형태의 레지스터(Memory Mapped Register)를 가지고 있다. 이런 연결 형태는 마이크로프로세서에서 주변 장치를 설정한 후 일반적인 메모리를 읽고 쓰는 것 같이 동작된다. 우선은 마이크로프로세서의 인터페이스를 설정한 후 레지스터의 모든 내용을 읽어서 제대로 레지스터의 값은 읽는지 장치에 대한 고유 ID(장치에 따라 제조사와 제품 ID를 읽을 수 있게 지원하기도 한다)는 제대로 읽히는지 검사하도록 한다.

이후 장치에 대한 전원 On/Off를 어떻게 하는지, 설정은 어떻게 읽고 변경하는지, 초기화는 어떻게 하는지 설정하게 된다. 이러한 기본적인 테스트가 끝나면 비로소 CE의 디바이스 드라이버 구조에 맞게 디바이스 드라이버 소스를 포팅하거나 개발한다.

필자는 디바이스 드라이버를 개발에 있어 Eboot(부트로더)에서 장치에 대한 모든 테스트를 반드시 선행했다. 이유는 하드웨어 팀과 소프트웨어 팀은 개발 일정에 따라서 각자 진행할 일이 많기 때문이다.

하드웨어 팀은 우선 하드웨어가 정상적으로 설계가 되었는지 검증이 필요하다. 검증 과정은 소프트웨어 팀의 도움이 없이는 불가능한 일이기 때문에 빠른 시간 내에 하드웨어를 검증하기 위한 작업에 들어가야 한다.

모든 하드웨어에 대한 기능 테스트를 다 할 수 없겠지만 ‘마이크로프로세서와 장치간의 인터페이스가 제대로 되는지’, ‘GPIO 포트에 대한 제어는 제대로 되는지’ 등의 설계된 하드웨어에 대한 검증 작업은 빠른 시간 내에 진행되어야 한다.

CE 개발 작업의 초기에는 이러한 하드웨어 검증 작업에 대한 개념이나 경험이 없기 때문에 간과하는 경우가 많았다. CE 운영체제가 제대로 동작되어야 LCD도 잘 돌아가 화면에 표시하는 테스트도 할 수 있었고 시리얼 통신의 문제 여부도 알 수 있었다.

그러다 보니 하드웨어에 대한 테스트가 미흡하여 정작 하드웨어 설계상의 문제를 나중에 발견하는 시행착오를 많이 겪었다. 그래서 요즘에는 아예 부트로더 단계에서 하드웨어에 대한 모든 테스트를 할 수 있도록 기능을 구현하는 방법을 시연 중이다.

하드웨어에 대한 테스트 작업을 하드웨어가 나왔을 때 바로 검증할 수 있도록 하고 하드웨어 팀은 다음 하드웨어 수정이나 디버깅 작업을 진행할 수 있게 한 후 드라이버를 개발하는 단계를 진행할 수 있게 했다.

하드웨어에 대한 검증 작업만 끝나면 다음 단계의 하드웨어가 나오기 까지는 어느 정도 여유가 있기 때문에 약간 여유롭게 드라이버를 개발할 수 있었다. 하드웨어에 대한 검증작업만 완벽히 한다면 디바이스 드라이버 구현은 문제가 없다. 디바이스 드라이버의 복잡도 때문에 어려움이 있을 수도 있지만 하드웨어의 테스트가 완벽하다면 개발은 시간문제다.

12. 디바이스 드라이버와 PM(Power Management)

PDA와 같은 휴대형 장치는 전원 관리가 매우 중요하다. 한번 충전으로 최소 며칠은 사용할 수 있어야 하기 때문이다. 물론 배터리의 용량을 늘리는 방법도 있지만, 이는 무한정 가능하지 않다. 따라서 한정된 용량을 최대한 효율적으로 이용할 수 있도록 시스템을 구현해야 한다.

제품에 따라 전원 관리에 대한 정책이 다를 수 있다. 휴대형 장치의 경우 전원 관리를 매우 주의해야 하지만 POS 단말기와 같이 전력을 계속 공급 받으면서 동작되는 장치의 경우에는 비교적 전원 관리가 쉽다. 사실 장치에 대한 On/Off만 제대로 되면 큰 문제가 없다.

개발하는 장치 이용도와 사용 환경에 따라 전원 관리 방침을 설계해야 한다. 사용자가 어떻게 사용할지 시나리오에 따른 사용량 예측 후 구현하는 것도 좋은 방법이다.

물론, 사용자 시나리오라는 것이 다양한 사용 변수가 있기 때문에 하루아침에 만들어질 수 있는 것은 아니다. 전원 관리는 개발 제품에 있어 중요한 문제기 때문에 초기 개발 시 부터 계획적인 구현이 필요하다.

CE 운영체제는 커널 내에 전원 관리 기능이 있으며 세부적인 전원 관리는 Power Manager인 PM.DLL에 의해서 이루어진다. 전체적인 관리는 커널 및 PM.DLL에 의해 이루어지지만 각각의 디바이스 드라이버는 전원 관리를 할 수 있는 구조로 만들어져야 한다.

CE의 전원 관리의 큰 방침은 전원관리에 대한 큰 골격은 제공하지만 세부적인 구현은 구현하는 개발자의 자율에 맡기는 것이다. 어떻게 보면 자유로움을 준다는 것도 있지만 초기 전원관리에 대한 개념을 잡는데 어려움이나 시행착오를 겪을 수 있는 사항이다.


<그림3>PM 구조

끝으로...

디바이스 드라이버에 관하여 간단히 알아 봤다. 디바이스 드라이버는 CE를 개발하는데 있어 많은 영역을 차지하는 부분이다. 가장 좋은 디바이스 드라이버는 사용자를 위한 드라이버라는 것을 명심하기를 바라며 마치겠다.

필자는?

필자 라영호는 2007, 2008 Microsoft Windows Embedded 분야 MVP이다. 모바일 관련 스마트폰 개발과 CE 관련 장치를 개발하고 있다. 개인적으로 운영하고 있는 CE에 관한 블로그(www.embeddedce.com)를 통해 CE 개발에 대한 다양한 생각과 방법론을 함께 생각해 보고자 노력 중이다. 최근에는 CE를 이용해 어떻게 빠르고 안정적인 시스템을 만들 것인가를 고민하고 있다. 아울러 CE의 포팅 뿐만 아니라 개발에서부터 최종 제품이 나오기까지 거쳐야 할 다양한 테스트 및 신뢰성 문제에도 관심을 가지고 있다. 조만간 CE에 대한 다양한 강좌 및 테스트에 관한 내용을 알릴 예정이라고 한다.

문자가 될경우 알려주시면 삭제 하겠습니다.

'이것저것 > Windows CE' 카테고리의 다른 글

SD 관련 자료  (0) 2009.11.10
SD/MMC Driver  (0) 2009.11.03
[Windows CE6.0] - tip?  (0) 2007.10.16
vmware에 wince6.0(cepc)올리기  (0) 2007.10.11
MMU의 등장  (0) 2007.09.18