1619, 1/81 회원가입  로그인  
   wolverine
   [자작] C 강좌 [7] - Pointer의 활용 (Device Driver)

http://www.hackerschool.org/HS_Boards/zboard.php?AllArticle=true&no=2040 [복사]



이번 장은 pointer의 또 다른 활용에 대해서 알아보겠습니다.

모든 Processor는 지원하는 최대 메모리 영역이 있으며,
이는 Processor의 address bus width에 의해서 결정이 됩니다.
만약 32-bit이면 2^32, 즉 4G Byte 까지 addressing(번지 지정)이 가능합니다.

사실 이러한 addressing(번지 지정) 가능한 전체 address 영역 전체에
모두 memory가 달려 있는 것은 아닙니다.
때로는 아무 것도 안 달려서 비어(empty or reserved) 있는 경우도 있고,
때로는 메모리와 동일한 interface를 가지는 Hardware Device(장치)들이 경우도 있습니다.
이러한 HW Device를 memory-mapped device라고 합니다.

HW device는 메모리 처럼 interface를 만들어서 processor가 읽고 쓰기를 할 수 있게 지원을 하고,
processor가 HW device 자신의 특정 번지에 어떤 값을 쓰면 특정 동작을 수행하게 됩니다.
또한, 동작의 결과값을 HW device 자신의 특정 번지에 저장시키면,
processor는 그 값을 일어서 현재 device의 동작 결과나 상태를 알 수 있게 됩니다.

예를 들어서,

0x00000000 ~ 0x000FFFFF (Memory)
0x00100000 ~ 0x001FFFFF (Empry/Reserved)
0x00200000 ~ 0x00200FFF (Device 1)
0x00201000 ~ 0x00201FFF (Device 2)
0x00202000 ~ 0x00202FFF (Device 3)

과 같이 memory와 memory-mapped device들이 함께 있을 수 있습니다.

[Note]
이전 강의에 언급했던 linker command file에서는
현재 system이 가지고 있는 memory 번지를 반드시 linker에게 알려주어야 합니다.
만약, linker command file에서 알려주는 실제 메모리 번지(Physical Memory Map)와
실제 system 구성이 다르게 되면,
실제 메모리가 없는 곳에 code를 올리고 변수를 할당(allocation) 하게되어
프로그램이 정상적으로 돌아가지 않습니다.

아무튼, Device Driver란 HW Device를 control 하기 위한 software를 말하며,
그러한 Device가 memory-mapped device 인 경우는 pointer를 이용해야 합니다.

예를 들어서 위의 device1 은
우리가 0x00200000 번지에 1을 쓰게 되면 device 1의 power가 on 이 되고,
0을 쓰게 되면 device 1의 power가 off가 된다
라고 가정을 하면,

int *a;

a = 0x00200000;

*a = 1; // Device 1 power on
*a = 0; // Device 1 power off

처럼 coding을 해서 software로 device 1을 제어 하게 됩니다.

위에 있는 4줄의 code가 바로 device driver 입니다.

Memory-Mapped Device 가 mapping된 메모리 영역은
변수와 같이 일반적인 메모리 영역으로는 사용하지 못합니다.
변수와 같이 읽고 쓰는 동작은 가능하지만,
모든 해당 address의 모든 bit가 읽기/쓰기를 지원하지 않습니다.
이러한 것을 memory-mapped device control register 라고 합니다.
이러한 영역을 마음데로 읽고 쓰기를 하면 system이 당연히 오동작을 하겠죠.

예를 들어서
0x00200000 Device 1 control register 는
다음과 같은 register function을 가질 수 있습니다.

bit [0]:      power on/off        (R/W)
bit [2:1]:   clk speed 0,1,2,3   (R/W)
bit [4:3]:   Device Version      (Read Only)
bit [7:5]:   Reserved                 (N/A)

부분적으로 read/write를 할 수 있지만,
나머지는 안되는 경우도 있습니다.

위와 같은 hw control register의 정보는
HW Datasheet로 제공되거나 system 설계자에 의해서 제공됩니다.
Device Driver 개발자는 위와 같이 제공되는 datasheet를 보고,
HW를 어떻게 구동시킬지 이해를 하고 있어야 합니다.
그런 다음 pointer를 이용해서 원하는 memory-mapped device control register를
읽고 쓰는 과정을 순차적으로 수행하게 됩니다.
이러한 code들이 바로 device driver 입니다.

int *a;
int devVersion;

a = 0x00200000;

/* Read and extract Device Version */
devVersion = (((*a)>>3) & 0x3);
printf("HW Device Version: %d", devVersion);

*a = 0x1        /* power on */
       | (0x2<<1);  /* set clock speed 2 */

위의 code는 예시된 control register 정보를 바탕으로 작성한
간단한 device driver 입니다.

Device driver를 개발할 때에,
c language와 pointer는 하나의 수단일 뿐입니다.
영어로 소설이나 시를 쓰기 위해서는 일단 영어를 배워야 하듯이,
device driver를 개발하기 위해서는 c 언어와 그중에서도 pointer를 반드시 알아야 합니다.

또한, Device driver 개발을 위해서는
HW에 대한 기본적인 지식이 필요하며,
다른 분야도 마찬가지 이겠지만, 영어는 필수입니다.
위에서 말한 HW datasheet는 대게 수십~수백 page의 영어로된 PDF 문서들 입니다.

[Note]
참고로 Device Driver는 위와 같이 직접적으로 HW를 제어하는 Code들입니다.
이러한 HW를 제어하는 device driver는 어떻게 보면 단순합니다.
만약 USB Driver를 짠다고 하면,
USB Device를 직접적으로 제어하는 low level device driver를 개발하고,
그러한 것들을 USB spec에 맞게 호출하여주는 코드가 필요합니다.
그러한 code를 Protocol Stack 이라고 합니다.
USB를 통해서 device driver는 물리적인 data를 보내고 받는 동작을 할 수 있습니다.
Protocol Stack은 USB 통신 규약에 따라서 작성된 code입니다.
Device Driver를 호출하는 역할을 합니다.
Protocol Stack은 USB spec.과 같은 통신 규약에 의해서 코드를 작성하기 때문에,
대부분 거의 동일하지만,
Device Driver는 USB controller HW를 만드는 회사에 따라서
주어진 HW에 맞게 달라지게 됩니다.

이번 장에서는 device driver를 개발할때에,
pointer가 어떤 식으로 이용이 되는지 알아보았습니다.
Device Driver는 어려운 분야가 아니라 생소한 분야일 뿐입니다.
누구나 HW에 대한 정보와 관심만 있으면 개발 할 수 있습니다.
그러기 위해서 c와 pointer는 필수 입니다.

이상으로 이번 장을 마칩니다.

Best Regards,
Wolverine



  Hit : 8836     Date : 2012/07/13 10:39



    
kbg06163 아직은 잘 모르겟네요 ㅠ, 2012/07/28  
cd80 항상 좋은 강의 정말 감사합니다 2012/07/30