2. 디바이스드라이버 [ DIO ] 2.1. 개요 타겟보드의데이터버스를이용하여 LED 및스위치동작을제어하는방법을설명하겠다. 2.2. 회로도 2.3. 준비조건 ARM 용크로스컴파일러가설치되어있어야한다. 하드웨어적인점검을하여정상적인동작을한다고가정한다. NFS(Network File System) 를사용할경우에는 NFS가마운트되어있어야한다. 여기서는소스전문을포함하지않았다. 만약소스전문을보기원한다면제공한 CD 를참조하기바란다. DIO 디바이스드라이버를어플리케이션에서사용하기위해서는타겟보드의 /dev 디렉토리에다음과같이디바이스노드를만들어야한다. $ mknod /dev/port c 241 0 이외의준비조건은앞절의 GIPO의준비조건과동일하다.
2.4. 회도도설명 74HC138의핀의기능은다음과같다. 핀번호 SYMBOL 설명 1,2,3 A, B, C Address inputs. 타겟보드의어드레스버스 A8,A9,A10을 74HC138 의 A,B,C에연결하였다. 4 G2A Enable input. 타겟보드의 ncs4 신호를연결하였다. "L" 일때 active 된다. 5 G2B Enable input. 타겟보드의 ncs4 신호를연결하였다. "L" 일때 active 된다. 6 G1 Enable input. "H" 일때 active 된다. 8 GND Ground. (0V) 15,14,13,12,11,10,9, 7 Y0 to Y7 Y0 to Y7 Outputs. 16 VCC Positive supply voltage. 74HC138의동작모드는다음과같다 입력 출력 G2A G2B G1 A B C Y0 Y1 Y2 Y3 Y4 Y5 Y6 Y7 L L H L L L L H H H H H H H L L H H L L H L H H H H H H 회로도를보면출력신호로 Y0, Y1 2개의신호만을사용하고있다. 따라서, 74HC138의동 작모드는이에대한입력만을처리하였다. 다른출력신호에대한입력을알고자한다면 74HC138의데이터시트를참조하면된다. 74HC574의핀의기능은다음과같다. 핀번호 SYMBOL 설명 1 OC 3-state output enable input. "L" 일때 active 된다. 2,3,4,5,6,7,8,9 D1 to D8 Data inputs. PXA255의데이터버스 D0~D7에연결하였다. 10 GND Ground. (0V) 11 CLK Clock input. "Low-to-High" 일때 active 된다. 19,18,17,16,15,14,13,12 Q1 to Q8 3-state flip-flop outputs. 20 VCC Positive supply voltage. 14장 디바이스드라이버
74HC574의동작모드는다음과같다. OC CLK Dn Q1 to Q8 L l L L h H H l Z H h Z Notes H = HIGH voltage level h = HIGH voltage level one set-up time prior to the LOW-to-HIGH CLK transition L = LOW voltage level l = LOW voltage level one set-up time prior to the LOW-to-HIGH CLK transition Z = HIGH impedance OFF-state = LOW-to-HIGh clock transition 74HC245의핀의기능은다음과같다. 핀번호 SYMBOL 설명 direction control. 핀의방향을결정한다. 1 DIR "H" 일때 An-to-Bn으로데이터를보낸다. "L" 일대 Bn-to-An으로데이터를보낸다. 2,3,4,5,6,7,8,9 A0 to A7 data inputs/outputs "DIR" 핀이 "L" 이면출력이된다. "DIR" 핀이 "H" 이면입력이된다. 10 GND Ground. (0V) 18,17,16,15,14,13,12,11 B0 to B7 data inputs/outputs "DIR" 핀이 "L" 이면입력이된다. "DIR" 핀이 "H" 이면출력이된다. 19 G output enable input."l " 일때 active 된다. 20 VCC Positive supply voltage. 74HC245의동작모드는다음과같다. G DIR An Bn L L A=B Inputs L H inputs B=A H X Z Z IC 에관한더자세한사항을알고자한다면해당 IC 의데이터시트를참조하면된다. 아래는위의회로도를구동하기위한시퀀스를설명한내용이다.
회로도에서 LED 출력을위해서는타겟보듸의 D0 ~ D7의데이터버스가 74HC574를통하여 LED에연결되어있다. 즉 D0 ~ D7의데이터버스에입력되는값에따라서 LED는 ON/OFF 하게된다. LED를 ON/OFF하기위해서는 74HC574의 CLK(clock) 를 Low-to-High 상태로만들어주어야만 D0 ~ D7의데이터값이출력이되어 LED를 ON/OFF 할수있다. 74HC574의 CLK(clock) 를 Low-to-High 상태로만들어주기위해서는 74HC138의 1번핀에연결되어있는타겟보드의 A8,A9,A10 어드레스버스에 LOW 신호를인가하고, 74HC138의 G2A 핀에연결되어있는타겟보드의 ncs4핀에 LOW-to-HIGH신호를인가하면된다. BASE Address : 0xF4000000 : ncs4 OFFSET Address : 0x000 : A8(LOW), A9(LOW), A10(LOW) 회로도에서스위치의입력을위해서는타겟보드의 D0 ~ D7의데이터버스가 74HC245를통하여스위치에연결되어있다. 즉, 스위치를누르면 D0 ~ D7의데이터버스를통하여스위치누름을감지할수있다. 여기서는 8개의스위치가 D0~D8 에연결되어있다. 스위치의동작을읽기위해서는 74HC245의 DIR 핀을 LOW로만들어주어야한다. 회로도를보면 DIR핀이그라운드에연결되어 LOW 상태가되어있음을알수있다. 단지제어해야할것은 74HC245의 G 핀을 LOW로만들어주기만하면된다. 74HC245의 G핀을 LOW상태로만들어주기위해서는 74HC138의 1번핀에연결되어있는타겟보드의 A8 어드레스버스에 HIGH 신호를인가, A9,A10 어드레드버스에 LOW 신호를인가하고, 74HC138의 G2A 핀에연결되어있는타겟보드의 ncs4핀에 LOW신호를인가하면된다. BASE Address : 0xF4000000 : ncs4 OFFSET Address : 0x100 : A8(HIGH), A9(LOW), A10(LOW) 2.5. 컴파일및실행 이디바이스드라이버및어플리케이션의컴파일및실행은이미앞절의 GPIO에서설명하였기에여기에서는더이상설명하지않겠다. 대신디바이스드라이버의소스를분석하기로하겠다. 소스전문을보기원한다면제공한 CD를참조하기바란다. 2.6. 디바이스드라이버소스분석 작업디렉토리는 /project/ez-s2410/port 디렉토리이다. 핵심부분만을설명하도록하겠다.
디바이스드라이버의 [/project/ez-s2410/port/dev_int.c ] 의내용중 int port_init(void ) 함수를보면장치드라이버를등록하고있다. int port_init( void ) // 장치를등록한다. ============================================ major &= 0xff; if(!register_chrdev( major, DEV_NAME, &port_fops ) ) printk(" register device %s OK (major=%d)\n", DEV_VERSION, major ); else printk(" unable to get major %d for %s \n", major, DEV_NAME ); return -EBUSY; return 0; IO 영역의등록을살펴보자. LED 출력은 74HC138의 G2A, G2B, A, B, C 핀이 LOW G1 핀이 HIGH 상태일때 Y0로 LOW가출력되어 74HCT574의 CLK 신호를움직여 LED 출력을하게된다. 스위치입력은 74HC138의 G2A, G2B, B, C 핀이 LOW A, G1 핀이 HIGH 상태일때 Y1로 LOW가출력되어 74HCT245의 noe 신호를움직여스위치입력을받게된다. 여기서, G2A 핀에는타겟보드의 ncs4가연결되어있고, A,B,C 핀에는타겟보드의 A8,A9,A10의어드레스신호가연결되어있다. NCS4는타겟보드에서정의하기를물리적주소는 0x20000000이고, 가상주소는 0xf4000000 에매핑되어있다. 이매핑은 arch/arm/mach-s3c2410 /mach-ez-s2410.c 에등록되어있다. 만약이파일을확인하여등록이되어있지않다면추가하고다시커널을컴파일하여타겟보드에올려야한다. static struct map_desc ez_s2410_iodesc[] initdata = /* virtual physical length domain */ 0xf1000000, S3C2410_CS1 +0x000000, 0x00100000, MT_DEVICE, // ncs1, CS8900 0xf1200000, S3C2410_CS1 +0x800000, 0x00100000, MT_DEVICE, // ncs1, REV1 0xf1300000, S3C2410_CS1 +0xc00000, 0x00100000, MT_DEVICE, // ncs1, REV2 ; 0xf2000000, S3C2410_CS2, 0x01000000, MT_DEVICE, // ncs2 0xf3000000, S3C2410_CS3, 0x01000000, MT_DEVICE, // ncs3 0xf4000000, S3C2410_CS4, 0x01000000, MT_DEVICE, // ncs4 0xf5000000, S3C2410_CS5, 0x01000000, MT_DEVICE, // ncs5
IO영역의범위및입 / 출력주소에대하여알아보기로하자. 이것에대한정의는 [ /project/ez-s24120/port/dev_int.h ] 에정의되어있다. /* 모듈관련 -------------------------------------------------------------------*/ #define DEV_MAJOR_DEF 241 #define DEV_VIRT_PORT_DEF 0xf4000000 // ncs4 #define DEV_PORT_SIZE_DEF 0x00001000 디바이스드라이버 open 시이주소가설정된다. LED 출력과스위치입력을위한 IO영역은 0xf4000000 ~ 0xf4000100 까지이다. LED 출력을위한주소는 74HC138의 A, B, C 핀이 LOW 상태로타겟보드에연결되어있는 A8,A9,A10 어드레스신호가 LOW 상태로되어야한다. 따라서 ncs4( 0xf4000000 ) + A8( 0x000) + A9(0x000) + A10(0x000) = 0xf4000000의어드레스신호가 LED 출력을위한주소이다. 스위치입력을위한주소는 74HC138의 B, C 핀이 LOW 상태이고, A 핀이 HIGH 상태로타겟보드에연결되어있는 A8 어드레스가 HIGH 상태로되어야한다. 따라서 ncs4 ( 0xf4000000 ) + A8(0x100) + A9(0x000) + A10(0x000) = 0xf4000100의어드레스신호가스위치입력을위한주소이다. 어플리케이션에서이주소를 ioctl 함수를통해서설정할수있게하였다. 디바이스드라이버의 [/project/ez-s2410/port/drv_port.c ] 의내용중 ioctl 함수와어플리케이션의 ioctl 함수접근하는소스를보여준다. [ioctl 함수 ] dev_port.c int port_ioctl( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ) dev_port_t *pdev = (dev_port_t *)filp->private_data; switch (cmd) case IOCTL_SET_PORT : set_port_t set_port; // 어플메모리에서복사한다. copy_from_user( (void *)&set_port, (void *)arg, sizeof(set_port_t) ); // 물리주소를가상주소를변경한다. pdev->virport = (volatile unsigned char *)set_port.virport; pdev->size = set_port.size; return 0; return -EINVAL;
[ 어플리케이션접근함수 ] app_port.c set_port.virport = 0xf4000100; // ncs4 set_port.size = 0x100; ioctl( fd, IOCTL_SET_PORT, &set_port ); [ioctl 인자구조체 ] dev_port.h typedef struct unsigned int virport; unsigned int size; set_port_t; 이디바이스드라이버를등록하고, 어플리케이션을실행시키면스위치입력에따라 LED 가 ON/OFF 하는것을확인할수있다.