Transcript
Page 1: 디바이스드라이버 응용

디바이스드라이버 응용

• 디바이스와 주소

• 디바이스 드라이버 구현 일반

• LED 디바이스 드라이버

• FND 디바이스 드라이버

• 키 매트릭스 디바이스 드라이버

• 문자형 LCD 디바이스 드라이버

• 도트 매트릭스 디바이스 드라이버

Page 2: 디바이스드라이버 응용

디바이스의 주소 지정 방식 전용 입출력 방식 (dedicated I/O 혹은 isolated I/O) 메모리 사상 입출력 방식 (memory mapped I/O)

Page 3: 디바이스드라이버 응용

PXA270 의 주소 공간

커널은 가상 주소를 사용해 컴퓨팅 자원에 접근 ARM 아키텍처의 디바이스를 접근하려면 물리 주소를 가상 메모리

공간으로 사상해야 작업 가능 디바이스의 접근은 시스템 모드에서 수행되므로 디바이스를 위한 가상

주소는 커널 공간 응용 프로그램은 커널 공간을 직접 제어할 수 없으며 커널도 사용자 공간을

직접 다룰 수 없음 따라서 디바이스 드라이버가 사용자와 커널 공간 사이에 데이터를

전송하려면 시스템호출과 같은 함수를 사용해야 함

Page 4: 디바이스드라이버 응용

타겟 시스템 디바이스들의 물리주소

Page 5: 디바이스드라이버 응용

디바이스 드라이버 제작 과정 디바이스 드라이버 소스 코드 작성 응용 프로그램 소스 코드 작성 디바이스 드라이버와 응용 프로그램의 컴파일 호스트 시스템에서 타겟 시스템으로 디바이스 드라이버와 응용

프로그램을 전송 디바이스 드라이버를 타겟 시스템 커널에 적재 타겟 시스템에서 응용 프로그램을 수행하여 테스트

Page 6: 디바이스드라이버 응용

실습 실습 LED 디바이스 드라이버 작성01 #include <linux/ioport.h>02 #include <asm/uaccess.h>03 #include <linux/module.h>04 #include <linux/fs.h>05 #include <asm/io.h>0607 #define LED_MAJOR 23908 #define LED_NAME "LED"09 #define LED_MODULE_VERSION "LED IO PORT V0.1"10 #define LED_ADDRESS 0x1240000011 #define LED_CS (*((volatile unsigned char *)(mem_base)))1213 static void *mem_base;14 unsigned long mem_addr, mem_len;1516 static int led_clear(void) {17 LED_CS = 0xFF;18 return 0;19 }2021 int led_open(struct inode *minode, struct file *mfile)22 {23 return 0;24 }2526 int led_release(struct inode *minode, struct file *mfile)27 {28 return 0;29 }3031 ssize_t led_write_byte(struct file *inode, const char *gdata, size_t length, loff_t

*off_what)32 {33 unsigned char c;34 get_user(c, (unsigned char *)gdata);35 LED_CS = c;36 return length;37 }

Page 7: 디바이스드라이버 응용

3839 static struct file_operations led_fops = {40 .owner = THIS_MODULE,41 .write = led_write_byte,42 .open = led_open,43 .release = led_release,44 };4546 int led_init(void)47 {48 int result;49 result = register_chrdev(LED_MAJOR, LED_NAME, &led_fops);50 if(result < 0) {51 printk(KERN_WARNING "can't get any major number.\n");52 return result;53 }54 mem_addr = LED_ADDRESS;55 mem_len = 0x1000;56 mem_base = ioremap_nocache(mem_addr, mem_len);57 if( !mem_base) {58 printk("Error mapping LED memory\n");59 release_mem_region(mem_addr, mem_len);60 return -EBUSY;61 }62 printk("init module, LED major number : %d\n", LED_MAJOR);63 return 0;64 }6566 void led_exit(void)67 {68 led_clear();69 if (unregister_chrdev(LED_MAJOR, LED_NAME))70 printk(KERN_WARNING"%s driver cleanup failed.\n", LED_NAME);71 iounmap(mem_base);72 }7374 MODULE_LICENSE("GPL");75 module_init(led_init);76 module_exit(led_exit);

실습 실습 LED 디바이스 드라이버 작성

Page 8: 디바이스드라이버 응용

01 #include <stdio.h>02 #include <stdlib.h>03 #include <unistd.h>04 #include <sys/types.h>05 #include <sys/stat.h>06 #include <fcntl.h>0708 int main(int argc, char **argv)09 {10 int dev;11 char buff;1213 if(argc <= 1) {14 printf("please input the parameter! ex)./test 0xa1\n");15 return -1;16 }1718 dev = open("/dev/LED", O_WRONLY);19 if (dev != -1) {20 if(argv[1][0] == '0' && (argv[1][1] == 'x' || argv[1][1] == 'X'))21 buff = (unsigned char)strtol(&argv[1][2], NULL, 16);22 else23 buff = atoi(argv[1]);24 write(dev, &buff, 1);25 close(dev);26 }27 else {28 printf( "Device Open ERROR!\n");29 exit(-1);30 }3132 return(0);33 }

실습 실습 LED 디바이스 드라이버 테스트 프로그램작성

Page 9: 디바이스드라이버 응용

③ LED 디바이스 프로그램 컴파일 위한 Makefile 작성 (11/led/Makefile)

01 KDIR := /embed/kernel/linux0203 obj-m := led.o0405 build:06 make -C $(KDIR) SUBDIRS=$(PWD) modules070809 clean:10 rm -rf *.o *.ko *.mod.c

실습 실습 LED 디바이스 드라이버 작성

Page 10: 디바이스드라이버 응용

④ 디바이스 드라이버와 응용프로그램을 컴파일

①②

③④

실습 실습 LED 디바이스 드라이버 작성

Page 11: 디바이스드라이버 응용

④ 생성한 모듈과 응용 프로그램을 타겟 시스템으로 전송 ⑤ 타겟 시스템에서 디바이스 드라이버를 적재→응용

프로그램 테스트

①② ③④⑤

실습 실습 LED 디바이스 드라이버 작성

Page 12: 디바이스드라이버 응용

9876543210

a

b

c

d

e

f g

dot

7- 세그먼트

실습 실습 FND 디바이스 드라이버 작성

Page 13: 디바이스드라이버 응용

001 #include <linux/module.h>……010 #include <asm/io.h>011012 #define FND_MAJOR 231013 #define FND_NAME "FND"014 #define MAX_FND 8015016 #define FPGA_FND_CS0 (0x11000000)……023 #define FPGA_FND_CS7 (0x11700000)024025 #define FND_CS0 (*((volatile unsigned char *)(mem_fnd_cs0)))……032 #define FND_CS7 (*((volatile unsigned char *)(mem_fnd_cs7)))033034 void *mem_fnd_cs0, *mem_fnd_cs1, *mem_fnd_cs2, *mem_fnd_cs3,*mem_fnd_cs4, *mem_fnd_cs5, *mem_fnd_cs6, *mem_fnd_cs7;035036 static char disp[8] = {0};037038 static int fnd_clear(void)039 {040 FND_CS0 = 0x00;……047 FND_CS7 = 0x00;048 return 0;049 }050

실습 실습 FND 디바이스 드라이버 작성

Page 14: 디바이스드라이버 응용

051 static int fnd_open(struct inode *minode, struct file *mfile)052 {053 fnd_clear();054 return 0;055 }056057 static int fnd_release(struct inode *minode, struct file *mfile)058 {059 return 0;060 }061062 static ssize_t fnd_write (struct file *filp, const char *buf,size_t count, loff_t *f_pos)063 {064 copy_from_user(disp, buf, count);065 FND_CS0 = disp[0]; mdelay(100);…………072 FND_CS7 = disp[7]; mdelay(100);073 return 0;074 }075076 static struct file_operations device_fops = {077 .owner = THIS_MODULE,078 .open = fnd_open,079 .write = fnd_write,080 .release = fnd_release,081 };082

실습 실습 FND 디바이스 드라이버 작성

Page 15: 디바이스드라이버 응용

083 static int fnd_init(void)084 {085 int result;086 unsigned long mem_addr_fnd0, mem_addr_fnd1, mem_addr_fnd2, mem_addr_fnd3, mem_addr_fnd4, mem_addr_fnd5,mem_addr_fnd6, mem_addr_fnd7;087 unsigned long mem_len;088089 result = register_chrdev(FND_MAJOR, FND_NAME, &device_fops);090 printk("FPGA %s MAJOR %d IRQ %d\n", FND_NAME, FND_MAJOR,result);091 mem_addr_fnd0 = FPGA_FND_CS0;……098 mem_addr_fnd7 = FPGA_FND_CS7;099 mem_len = 0x1000;100101 mem_fnd_cs0 = ioremap_nocache ( mem_addr_fnd0, mem_len);102 if( !mem_fnd_cs0) {103 printk("Error mapping fnd0 memery");104 return -EBUSY;105 }……143 mem_fnd_cs7 = ioremap_nocache ( mem_addr_fnd7, mem_len);144 if( !mem_fnd_cs7) {145 printk("Error mapping fnd7 memery");146 return -EBUSY;147 }148 return 0;149 }150151 static void fnd_exit(void)152 {153 fnd_clear();154 iounmap(mem_fnd_cs0);……161 iounmap(mem_fnd_cs7);162 unregister_chrdev(FND_MAJOR, FND_NAME);163 printk("%s unregisterd.\n", FND_NAME);164 }165 MODULE_LICENSE("GPL");166 module_init(fnd_init); // 모듈을 커널에 등록시 fnd_init 함수 호출167 module_exit(fnd_exit); // 커널에서 모듈 제거시 fnd_exit 함수 호출

실습 실습 FND 디바이스 드라이버 작성

Page 16: 디바이스드라이버 응용

01 #include <stdio.h>02 #include <fcntl.h>0304 #define MAXFND 80506 static char fndDev[] = "/dev/FND";07 static int fndFd = (-1);0809 asc2fnd(char *s, int n)10 {11 char c;12 while (n-- > 0) {13 c = *s;14 switch (c) { // 여러 가지 문자 추가 가능15 case '0': c = 0x3f; break;……24 case '9': c = 0x67; break;25 default: c = 0x00; break;26 }27 *s++ = c;28 }29 }3031 main(int ac, char *av[])32 {33 int n;34 char buf[MAXFND+1];3536 fndFd = open( fndDev, O_RDWR);37 if (fndFd < 0) {38 fprintf(stderr, "cannot open FND (%d)", fndFd);39 exit(2);40 }41 memset(buf, 0, sizeof(buf));42 if (ac > 1) {43 n = strlen(av[1]);44 if (n > MAXFND)45 n = MAXFND;46 memcpy(buf, av[1], n);47 }48 asc2fnd(buf, MAXFND);49 write(fndFd, buf, MAXFND);50 }

실습 실습 FND 디바이스 드라이버 작성

Page 17: 디바이스드라이버 응용

③ FND 디바이스 드라이버 프로그램을 컴파일하기 위한 Makefile 작성

④ 디바이스 드라이버와 응용프로그램을 컴파일 ⑤ 기존 디바이스 드라이버를 테스트한 후에 삭제

①②③

실습 실습 FND 디바이스 드라이버 작성

Page 18: 디바이스드라이버 응용

⑥ 새로 생성한 디바이스 드라이버와 응용 프로그램을 타겟 시스템으로 전송

⑦ 응용프로그램을 실행한 후 임의의 키를 눌러 결과를 관찰

①②

③④

실습 실습 FND 디바이스 드라이버 작성

Page 19: 디바이스드라이버 응용

키 매트릭스 디바이스 드라이버 작성

Page 20: 디바이스드라이버 응용

하나 이상의 프로세스에 비동기적인 사건을 알리기 위해 사용 디바이스 , 오류 상황 , 인터럽트 키 사용 등의 경우 발생

사용자 프로그램에서 사용하는 시그널 함수의 형식

디바이스 드라이버에서 사용자 프로그램에 시그널을 보내는 함수의 형식

#include <signal.h>void (*signal(int signum, void(*handler)(int))) (int);

int kill_proc(pid_t pid, int signum, int priv);

시그널 함수

Page 21: 디바이스드라이버 응용

시그널 사용법

Page 22: 디바이스드라이버 응용

타이머 인터럽트 : 주기적으로 인터럽트를 발생시켜 반복해서 처리해야 할 작업에 사용

타이머 인터럽트는 HZ( 아키텍처에 의존적인 값 ) 로 설정 타이머 인터럽트가 발생하면 스케줄러에 의해 새로운

작업을 스케줄하고 jiffies( 운영체제가 부팅된 시점부터 발생한 클록 회수 ) 값을 증가

커널 타이머를 사용해 특정 작업을 정해진 시간에 실행 “jiffies ≧ timer->expires” 조건을 만족할 때 타이머에

등록한 함수를 실행 expires 는 jiffies 와 타이머 간격을 합한 값

커널 타이머

Page 23: 디바이스드라이버 응용

커널 타이머의 사용법

Page 24: 디바이스드라이버 응용

001 #include <linux/module.h>-------------010 #include <asm/io.h>011012 #define KEY_MAJOR 233013 #define KEY_NAME "KEY"014 #define SCAN_NUM 4015016 #define FPGA_KEY_OUT (0x11D00000)017 #define FPGA_KEY_IN (0x11E00000)018019 #define KEYOUT (*(volatile unsigned char *)mem_key_out)020 #define KEYIN (*(volatile unsigned char *)mem_key_in)021022 static void *mem_key_out, *mem_key_in;023 static struct timer_list key_timer_str;024 static unsigned char key_data;025 static pid_t id;026 static int n = 1;027028 int key_open (struct inode *inode, struct file *filp)029 {030 return 0;031 }032033 int key_release (struct inode *inode, struct file *filp)034 {035 del_timer(&key_timer_str);036 return 0;037 }038

실습 실습 키 매트릭스 디바이스 드라이버 작성

Page 25: 디바이스드라이버 응용

039 ssize_t key_read (struct file *filp, char *buf, size_tcount, loff_t *f_pos)040 {041 copy_to_user(buf, &key_data, sizeof(key_data));042 return 0;043 }044045 void timer_function(unsigned long data)046 {047 unsigned int i, in, out;048049 for(i=0; i<4; i++) {050 out = (1 << i);051 KEYOUT = out;052 in = ((KEYIN) & (0x0F));053 out =((out) << 4);054 if (in != 0) {055 key_data = ((out) | (in));056 kill_proc(id, SIGUSR1, 1);057 }058 }059 key_timer_str.expires = jiffies + (HZ/100);060 add_timer(&key_timer_str);061 }062063 ssize_t key_write (struct file *filp, const char *buf, size_tcount, loff_t *f_pos)064 {065 get_user(id,(int*)buf);066 init_timer(&key_timer_str);067 key_timer_str.expires = jiffies + (HZ/100);068 key_timer_str.data = (unsigned long)n;069 key_timer_str.function = &timer_function;070 add_timer(&key_timer_str);071 return 0;072 }073

실습 실습 키 매트릭스 디바이스 드라이버 작성

Page 26: 디바이스드라이버 응용

074 struct file_operations key_fops = {075 .owner = THIS_MODULE,076 .read = key_read,077 .write = key_write,078 .open = key_open,079 .release = key_release,080 };081082 static int key_init(void)083 {084 int result;085 unsigned long mem_addr_out, mem_addr_in, mem_len;086087 result = register_chrdev(KEY_MAJOR, KEY_NAME, &key_fops);……092 mem_addr_out = FPGA_KEY_OUT;093 mem_addr_in = FPGA_KEY_IN;094 mem_len = 0x1000;095 mem_key_out = ioremap_nocache (mem_addr_out, mem_len);……100 mem_key_in = ioremap_nocache (mem_addr_in, mem_len);……105 printk("FPGA %s MAJOR %d\n", KEY_NAME, KEY_MAJOR);106 return 0;107 }108109 static void key_exit(void)110 {111 unregister_chrdev (KEY_MAJOR, KEY_NAME);112 }113114 MODULE_LICENSE("GPL");115 module_init(key_init);116 module_exit(key_exit);

실습 실습 키 매트릭스 디바이스 드라이버 작성

Page 27: 디바이스드라이버 응용

01 #include <stdio.h>……08 #include <linux/delay.h>0910 static int dev;11 static unsigned char vkey;1213 void keysignal(int sig)14 {15 read(dev, &vkey, 1);16 printf("SIGNAL occur!!!!\n");17 }1819 int main(void)20 {21 pid_t id;2223 if ((dev = open("/dev/KEY", O_RDWR)) < 0) {24 printf("return Value is %d\n",dev);25 perror("open failed /dev/KEY");26 close(dev);27 exit(-1);28 }29 (void) signal (SIGUSR1, keysignal);30 id = getpid();31 write(dev, &id, 4);32 printf("press the push button!\n");33 (void) signal (SIGUSR1, keysignal);34 while(1) {35 if(vkey != 0) {36 printf("vkey is 0x%x\n", vkey);37 vkey=0;38 }39 }40 close(dev);41 return 0;42 }

실습 실습 키 매트릭스 디바이스 드라이버 작성

Page 28: 디바이스드라이버 응용

③ Makefile 을 작성 ④ 디바이스 드라이버 모듈과 응용 프로그램을 컴파일 ⑤ 기존 디바이스 드라이버를 테스트 후 삭제

실습 실습 키 매트릭스 디바이스 드라이버 작성

Page 29: 디바이스드라이버 응용

⑥ 생성한 디바이스 파일과 응용프로그램을 타겟 시스템으로 전송

⑦ 디바이스 드라이버를 커널로 적재하고 새로운 디바이스 파일을 만든 후 응용프로그램으로 테스트

①②③

④⑤

실습 실습 키 매트릭스 디바이스 드라이버 작성

Page 30: 디바이스드라이버 응용

타겟 시스템은 HD44780 LCD 컨트롤러 모듈을 사용

16 문자씩 2 라인으로 표시 . 폰트는 5 * 7 도트 .

제어를 위한 2 개의 제어 비트 (RS, R/W’) 와 데이터 비트 (D0~D7) 에 [ 표 11-5] 의 명령어로 설정한 후 Enable 클록을 On/Off함으로써 문자형 LCD 로 데이터를 전송

Page 31: 디바이스드라이버 응용
Page 32: 디바이스드라이버 응용
Page 33: 디바이스드라이버 응용

실습 실습 문자형 LCD 디바이스 드라이버 작성001 #include <linux/module.h>……009 #include <asm/io.h>010011 #define CLCD_MAJOR 238012 #define CLCD_NAME "CLCD"013014 #define FPGA_CLCD_WR_ADD (0x12300000)015 #define FPGA_CLCD_RS_ADD (0x12380000)016 #define CLCD_CMD_ADDR (*((volatile unsigned char*)(mem_base_wr)))017 #define CLCD_DATA_ADDR (*((volatile unsigned char*)(mem_base_rs)))018019 static void *mem_base_wr, *mem_base_rs;020 static unsigned long mem_addr_wr, mem_addr_rs, mem_len;021022 static void lcd_init(void)023 {024 CLCD_CMD_ADDR = 0x38;025 mdelay(300);026 CLCD_CMD_ADDR = 0x0e;027 mdelay(100);028 CLCD_CMD_ADDR = 0x02;029 mdelay(100);030 CLCD_CMD_ADDR = 0x01;031 mdelay(100);032 }033034 static void string_out(char *str)035 {036 char *s;037 int i=0;038039 printk("%s\n", str);040 lcd_init();041 for (s=str; *s; s++) {042 CLCD_DATA_ADDR = *s;043 if(i == 15) {044 udelay(100);045 CLCD_CMD_ADDR = 0xC0;046 }047 udelay(100);048 i++;049 }050 }

Page 34: 디바이스드라이버 응용

……062 ssize_t clcd_write (struct file *filp, const char *buf, size_t count, loff_t *f_pos)063 {064 char data[32];065066 memset(data, 0 , 32);067 copy_from_user(data, buf, count);068 string_out(data);069 return 0;070 }071072 struct file_operations clcd_fops = {073 .owner = THIS_MODULE,074 .write = clcd_write,075 .open = clcd_open,076 .release = clcd_release,077 };078079 static int clcd_init(void)080 {081 int result;082083 result = register_chrdev(CLCD_MAJOR, CLCD_NAME, &clcd_fops);……088 mem_addr_wr = FPGA_CLCD_WR_ADD;089 mem_addr_rs = FPGA_CLCD_RS_ADD;090 mem_len = 0x1000;091092 mem_base_wr = ioremap_nocache ( mem_addr_wr, mem_len);……098 mem_base_rs = ioremap_nocache ( mem_addr_rs, mem_len);……103 printk("FPGA %s MAJOR %d\n",CLCD_NAME, result);104 return 0;105 }106107 static void clcd_exit(void)108 {109 unregister_chrdev(CLCD_MAJOR, CLCD_NAME);110 iounmap(mem_base_wr);111 iounmap(mem_base_rs);112 }113114 MODULE_LICENSE("GPL");115 module_init(clcd_init);116 module_exit(clcd_exit);

실습 실습 문자형 LCD 디바이스 드라이버 작성

Page 35: 디바이스드라이버 응용

01 #include <stdio.h>02 #include <fcntl.h>03 #include <stdlib.h>04 #include <unistd.h>0506 static char lcdDev[] = "/dev/CLCD";07 static int lcdFd = -1;0809 #define MAXCHR 321011 int main(int argc, char **argv)12 {13 int n;14 char buf[MAXCHR];1516 lcdFd = open(lcdDev, O_RDWR);17 if (lcdFd < 0) {18 fprintf(stderr, "cannot open CLCD (%d)", lcdFd);19 exit(2);20 }21 }22 strcpy(buf, "Hi, Character LCD!\n");23 if (argc > 1) {24 memset(buf, 0, sizeof(buf));25 n = strlen(argv[1]);26 if (n > MAXCHR)27 n = MAXCHR;28 memcpy(buf, argv[1], n);29 }30 write(lcdFd, buf, MAXCHR);31 return 0;32 }

실습 실습 문자형 LCD 디바이스 드라이버 작성

Page 36: 디바이스드라이버 응용

③ 문자 LCD 디바이스 드라이버 프로그램을 컴파일하기 위한 Makefile 을 작성

④ 디바이스 드라이버 모듈과 응용 프로그램을 컴파일 ⑤ 기존 디바이스 드라이버와 디바이스 파일을 테스트한 후

삭제

①②③

실습 실습 문자형 LCD 디바이스 드라이버 작성

Page 37: 디바이스드라이버 응용

⑥ 생성한 디바이스 드라이버와 응용 프로그램을 타겟 시스템으로 전송

⑦ 디바이스 드라이버를 커널로 적재하고 필요한 디바이스 파일을 생성한 후 테스트

①②

실습 실습 문자형 LCD 디바이스 드라이버 작성

Page 38: 디바이스드라이버 응용

LED 들을 매트릭스 형태로 배선시킨 구조 LED 를 점등해 원하는 글씨나 그림을 나타내는 디바이스 5 개의 열에는 주소 버스가 연결 , 7 개의 행에는 데이터 버스가

연결됨

0x1180_00000x1190_00000x11A0_00000x11B0_00000x11C0_0000

Page 39: 디바이스드라이버 응용

실습 실습 도트 매트릭스 디바이스 드라이버 작성

001 #include <linux/module.h>……009 #include <asm/io.h>010011012 #define DOT_MAJOR 232013 #define DOT_NAME "DOT"014015 #define FPGA_DOT_COL_1 (0x11800000)……019 #define FPGA_DOT_COL_5 (0x11C00000)020021 static void *mem_dot_col1, *mem_dot_col2, *mem_dot_col3, *mem_dot_col4, *mem_dot_col5;022023 #define DOT_COL_1 (*((volatile unsigned char *)(mem_dot_col1)))……027 #define DOT_COL_5 (*((volatile unsigned char *)(mem_dot_col5)))028029 void dot_test(void)030 {031 unsigned short dot_table[10][5] = {032 {0x7F, 0x41, 0x41, 0x41, 0x7F},033 {0x00, 0x00, 0x7F, 0x00, 0x00},……041 {0x78, 0x48, 0x48, 0x48, 0x7F}042 };043 int i;044045 for(i=0; i < 10; i++) {046 DOT_COL_1 = dot_table[i][0];……050 DOT_COL_5 = dot_table[i][4];051 mdelay(500);052 }053 }054

Page 40: 디바이스드라이버 응용

055 int dot_open (struct inode *inode, struct file *filp)056 {057 DOT_COL_1 = 0x00;……061 DOT_COL_5 = 0x00;062 return 0;063 }……070 int dot_ioctl(struct inode *inode, struct file *filp, unsignedint cmd, unsigned long arg)071 {072 switch(cmd) {073 case 1:074 dot_test();075 break;076 default:077 return 0;078 }079 return 0;080 }081082 struct file_operations dot_fops = {083 .owner = THIS_MODULE,084 .open = dot_open,085 .ioctl = dot_ioctl,086 .release = dot_release,087 };088089 static int dot_init(void)090 {091 int result;092 unsigned long mem_addr_col1, mem_addr_col2, mem_addr_col3,mem_addr_col4,

mem_addr_col5;093 unsigned long mem_len;094095 result = register_chrdev(DOT_MAJOR, DOT_NAME, &dot_fops);

실습 실습 도트 매트릭스 디바이스 드라이버 작성

Page 41: 디바이스드라이버 응용

096 if(result < 0)097 {098 printk(KERN_ERR " DOT : failed to register device.\n");099 return result;100 }101 mem_addr_col1 = FPGA_DOT_COL_1;……105 mem_addr_col5 = FPGA_DOT_COL_5;106 mem_len = 0x1000;107108 mem_dot_col1 = ioremap_nocache ( mem_addr_col1, mem_len);……131 mem_dot_col5 = ioremap_nocache ( mem_addr_col5, mem_len);……136137 printk("FPGA %s, MAJOR %d\n", DOT_NAME, result);138 return 0;139 }140141 static void dot_exit(void)142 {143 unregister_chrdev(DOT_MAJOR, DOT_NAME);144 iounmap(mem_dot_col1);……148 iounmap(mem_dot_col5);149 }150151 MODULE_LICENSE("GPL");152 module_init(dot_init);153 module_exit(dot_exit);

실습 실습 도트 매트릭스 디바이스 드라이버 작성

Page 42: 디바이스드라이버 응용

01 #include <stdio.h>02 #include <fcntl.h>03 #include <sys/ioctl.h>0405 static char dotDev[] = "/dev/DOT";06 static int dotFd = -1;0708 int main()09 {10 dotFd = open(dotDev, O_RDWR );1112 if ( dotFd < 0 ) {13 fprintf(stderr, "cannot open DOT (%d)", dotFd);14 exit(2);15 }1617 ioctl(dotFd, 1, 0);18 return 0;19 }

실습 실습 도트 매트릭스 디바이스 드라이버 작성

Page 43: 디바이스드라이버 응용

③ 도트 디바이스 프로그램 컴파일하기 위한 Makefile 을 작성

④ 디바이스 드라이버 모듈과 응용 프로그램을 컴파일 ⑤ 기존 디바이스 드라이버를 테스트한 후 디바이스

드라이버와 디바이스 파일을 삭제

①②③

실습 실습 도트 매트릭스 디바이스 드라이버 작성

Page 44: 디바이스드라이버 응용

⑥ 생성한 디바이스 파일과 응용프로그램을 타겟 시스템으로 전송

⑦ 디바이스 드라이버를 커널로 적재하고 새로운 디바이스 파일을 만든 후 응용프로그램으로 테스트

①②③

실습 실습 도트 매트릭스 디바이스 드라이버 작성

Page 45: 디바이스드라이버 응용

ARM 계열의 CPU 는 메모리 사상 입출력 방식을 취한다 . 각 장치들의 하드웨어 특성이 서로 다르므로 동작방식을 잘

이해하고 디바이스 드라이버를 작성해야 한다 . LED 디바이스 드라이버는 사용자 공간에서 데이터를 받아

LED 가 위치한 가상 주소로 출력하도록 프로그램한다 . FND 는 7-segment 라고도 하며 응용 프로그램에서 글자

모양을 만들어 디바이스 드라이버를 통해 출력한다 . 키 매트릭스 디바이스 드라이버는 타이머를 사용해

폴링으로 눌려진 키를 식별하도록 작성한다 . 문자형 LCD 디바이스 드라이버는 해당 장치의

레지스터로 데이터를 전송하여 출력한다 . 도트 매트릭스 디바이스 드라이버는 구성된 도트의 각 열

별로 데이터를 출력하도록 프로그램한다 .