FND (Flexible Numeric Display)

Slides:



Advertisements
Similar presentations
YES C 제 1 장 C 언어의 개요 1/34 제 1 장 C 언어의 개요 문봉근. YES C 제 1 장 C 언어의 개요 2/34 제 1 장 C 언어의 개요 1.1 프로그램과 C 언어의 특징 1.2 C 언어의 프로그램 구성 1.3 비주얼 C++ 통합 환경 들어가기.
Advertisements

마이크로 시스템 1 선 덕 한선 덕 한 lecture7. LCD 구동. 마이크로 시스템 2 강의 목표 현재 디스플레이 장치로써 가장 널리 사용되어지는 LCD 을 프로세서 에서 어떻게 제어 하는지 알아본다.
1.
제10장 디바이스 드라이버.
QT/Embedded와 웹 서버 Qt/Embedded 개요 Qt/Embedded 개발 환경 구축
제 3 장 변수와 자료형.
KEY 디바이스 드라이버 Lecture #12. 2 차례 GPIO 및 Control Registers KEY 하드웨어 구성 KEY Driver 프로그램 key-driver.c 시험 응용 프로그램 key-app.c.
FND 디바이스 드라이버 Lecture #13.
5장. Enhanced Char Driver Operations 과제
TextLCD 디바이스.
FND 디바이스 드라이버 Lecture #11.
실습 7-3 gdb 분석을 통해 취약 프로그램의 힙 버퍼 오버플로우 개념 이해하기
Linux System Programming
Kernel Programming Kernel
Department of Computer Engineering
디바이스 드라이버 (Device Driver)
디바이스 드라이버 기초 디바이스 드라이버의 개요 파일 연산 디바이스 드라이버 등록 디바이스 드라이버 구성
디바이스 드라이버 응용 디바이스와 주소 디바이스 드라이버 구현 일반 LED 디바이스 드라이버 FND 디바이스 드라이버
디바이스 드라이버.
이식성과 데이터형 서로 다른 프로세서 상에서의 이식성을 위해 가급적 리눅스 커널이 제공하는 데이터형을 사용하는 것이 좋다.
PCI가 어렵울 거라는 생각을 지금부터 버리도록 합시다.
디바이스 드라이버 개요 가상 디바이스드라이버 실습
제3장 추가 실습 3장 관련 C 언어 프로그래밍 실습.
쉽게 풀어쓴 C언어 Express 제18장 입출력과 라이브러리 함수 C Express.
쉽게 풀어쓴 C언어 Express 제17장 동적 메모리와 연결 리스트 C Express.
쉽게 풀어쓴 C언어 Express 제4장 변수와 자료형 C Express.
Network Lab. Seoung Hyeon, Lee
버퍼 오버플로우에 대한 대책과 발전된 공격 안전한 함수 사용 버퍼 오버플로우에 취약한 함수 사용하지 않기
Linux System Programming
MicroC/OS-II Lab. 경희대학교 컴퓨터공학과 조 진 성.
제 12장 I/O멀티플렉싱(Multiplexing)
10장 메모리 관리.
쉽게 풀어쓴 C언어 Express 제17장 동적 메모리와 연결 리스트 C Express.
Department of Computer Engineering
AVR - Chapter 15 황 지 연.
Step Motor Device Driver
fork로 생성한 자식 프로세스에서 exec 함수군을 호출
Input/Output Control.
링크 파일 생성[1] 링크 하드링크 생성 : link(2) 이미 있는 파일이나 디렉토리에 접근할 수 있는 새로운 이름
Term Project Team Member
파일 기술자 복사 파일 기술자 복사 : dup(2) 파일 기술자 복사 : dup2(3)
(ioctl, mmap, fsync&flush)
임베디드 실습 # LED, 7’Segment 제어
6장 파일 및 레코드 잠금.
제 2 장 변수와 상수.
커널 모듈 프로그래밍 (Kernel Module Programming)
Department of Computer Engineering
HBE-SMIII-SV210 리눅스 커널과 디바이스 드라이버
제 3 장 상수와 변수
10장 C 표준 파일 입출력 子曰 學而時習(실습?)之 不亦悅乎.
9. 아두이노를 이용한 FND 제어 - 스마트 폰으로 제어하는 아두이노 -.
adopted from KNK C Programming : A Modern Approach
문자 디바이스 드라이버 임베디드 시스템.
Memory & Data Management.
컴퓨터의 기초 제 2강 - 변수와 자료형 , 연산자 2006년 3월 27일.
리눅스 디바이스 드라이버 (Linux Device Driver)
제어문 & 반복문 C스터디 2주차.
3장. 변수와 연산자. 3장. 변수와 연산자 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, / 3-1 연산자, 덧셈 연산자 연산자란 무엇인가? 연산을 요구할 때 사용되는 기호 ex : +, -, *, /
WinCE Device Driver 실습 #2
Stepper Motor 디바이스 드라이버
C 코드최적화 세명대학교 AI연구실 양승조.
Department of Computer Engineering
LCD.
Kernel Programming Kernel
argc, argv 의 사용방법 #include <stdio.h>
06. 디바이스의 등록과 해제 김진홍
C 13장. 입출력 라이브러리 #include <stdio.h> int main(void) { int num;
WinCE Device Driver 실습 #2
printf("Global Korea\n");
3장 파일 다루기 한빛미디어(주).
Presentation transcript:

FND (Flexible Numeric Display)

FND 어드레스 디코딩 회로 설명 개요 7 세그먼트라고도 하고 숫자나 간단한 기호 표현에 많이 이용. 7-segment LED는 A-G 의 7개의 LED와 소수점 표시를 한 DP (Decimal Point)의 LED 1개로 구성된다. 각 LED는 표시되는 문자의 일부분을 구성하므로 각각을 세그먼트(segment : 부분, 구분)라 부른다.

FND 제어용 Device Driver FND 디바이스 물리 주소 영역 nCS4번 영역인 0x1000_0000 ~ 0x13FF_FFFF 사이에 FND 존재

FND 제어용 Device Driver IEB 보드 어드레스 디코딩 회로 CS4에 의해 어드레스 디코딩과 버퍼의 역할을 하는 FPGA 칩이 활성화

FND 제어용 Device Driver FND 어드레스 FND 물리주소(접근번지)는 0x1100_0000 ~ 0x1170_0000 영역에 8개가 할당 되어있는데 adress table을 구성해서 보면 최상위 6bit(A31~26)가 CS4 해당하고, 나머지 26bit중 최상위 6bit(A25~20)가 실질적인 어드레스 디코딩을 위해 사용되고 있다.

FND 제어용 Device Driver FND 어드레스 디코딩 회로 구성 data[31..0] D- 플리 플롭 FND의 물리주소 FND_CS0 ~ FND_CS7가 주어지면 CS4에 의해 FPGA가 선택되고 FPGA 내부에 있는 어드레드 디코딩 논리 회로에 의해 활성화 신호가 발생하고 해당 FND에 D-플리플롭에 상승엣지가 공급되어 FND에 연결된 데이타버스 하위 8비트가 FND에 전달되어 FND의 불을 켜게 된다.

FND 제어용 Device Driver FND 제어 방법(해당 비트에 데이터를 보냄) FND 1 : FND_CS = (0x01 << 0) 7 : FND_CS = (0x01 << 6) FND 6 : FND_CS = (0x01 << 5) 2 : FND_CS = (0x01 << 1) 5 : FND_CS = (0x01 << 4) 3 : FND_CS = (0x01 << 2) 8 : FND_CS = (0x01 << 7) 4 : FND_CS = (0x01 << 3)

FND 제어용 Device Driver 가상주소 맵핑 MMU를 사용하는 리눅스에서는 물리주소를 가지고 디바이스에 접근하면 페이지 폴트가 발생한다. 따라서 커널이 사용하는 가상주소를 할당받아 야 한다. ioremap 함수는 해당하는 디바이스를 위해 메모리 상에 일정영역을 커널이 관리하는 가상주소를 맵핑하여 준다. 따라서 FND에 해당하는 가상주소로 ioremap함수를 이용하여 FND를 위한 가상주소를 얻어와야 한다.

FND 제어용 Device Driver 소스 설명 Makefile fnd.c : lcd 디바이스 드라이버 소스이다. fnd.ko : lcd 디바이스 드라이버를 컴파일하면 생성되는 object 파일이다. fnd_test.c : lcd 디바이스 드라이버를 테스트하는 어플리케이션 소스이다.

FND 제어용 Device Driver FND 드라이버 소스 설명 (fnd.c) #define FPGA_FND_CS0 (0x11000000) //FND 물리주소 #define FPGA_FND_CS1 (0x11100000) #define FPGA_FND_CS2 (0x11200000) #define FPGA_FND_CS3 (0x11300000) #define FPGA_FND_CS4 (0x11400000) #define FPGA_FND_CS5 (0x11500000) #define FPGA_FND_CS6 (0x11600000) #define FPGA_FND_CS7 (0x11700000)

FND 제어용 Device Driver FND 드라이버 소스 설명 (fnd.c) mem_addr_fnd0 = FPGA_FND_CS0; …… mem_len = 0x1000; ….. static int fnd_init(void){ mem_fnd_cs0 = ioremap_nocache ( mem_addr_fnd0, mem_len); //가상주소 얻기 if( !mem_fnd_cs0) { printk("Error mapping fnd0 memery"); return -EBUSY; } ……. static void fnd_exit(void){ fnd_clear(); unregister_chrdev(FND_MAJOR, FND_NAME); iounmap(mem_fnd_cs0);

FND 제어용 Device Driver FND 응용프로그램 소스 설명 (fnd_test.c) unsigned char asc_to_fnd(int n){ unsigned char c; switch (n) { /* 여러가지 문자를 추가할수 있다 */ case 0: c = 0x3f; break; case 1: c = 0x06; break; case 2: c = 0x5b; break; case 3: c = 0x4f; break; case 4: c = 0x66; break; case 5: c = 0x6d; break; case 6: c = 0x7d; break; case 7: c = 0x07; break; ….. } return c;

FND 제어용 Device Driver FND 응용프로그램 소스 설명 (fnd_test.c) main(int ac, char *av[]){ int n, count, dev; unsigned char buf[MAXFND+1]; dev = open( fnd_dev, O_RDWR); if (dev < 0) { fprintf(stderr, "cannot open FND (%d)", dev); exit(2); } memset(buf, 0, sizeof(buf)); for (n = 0 ; n <= 9; n++) { for( count = 0 ; count < MAXFND; count++){ buf[count]= asc_to_fnd(n); write(dev, buf, MAXFND); usleep(500000);

FND 제어용 Device Driver Makefile 설명 CC := /opt/iwmmxt-1.0.0/bin/arm-linux-gcc KDIR := /PXA270/kernel/linux-2.6.11-h270-tku_v1.1 TEST_TARGET = fnd_test TEST_OBJS = fnd_test.o TEST_SRCS = fnd_test.c obj-m := fnd.o build: $(TEST_TARGET) make -C $(KDIR) SUBDIRS=`pwd` modules $(TEST_TARGET) : $(TEST_OBJS) $(CC) -o $@ $(TEST_OBJS) clean: rm -rf *.o *.ko *.mod.c rm -f $(TEST_TARGET)

FND 제어용 Device Driver # make clean # make 다운로드 : fnd.ko, fnd_test 실행방법 이미 타겟보드에 fnd의 드라이버가 올라가 있으므로 rmmod로 제거한 후 자신이 만든 fnd드라이버를 올리고 실행시켜보자. (host) # make clean # make 다운로드 : fnd.ko, fnd_test 실행 hybus~>#./fnd_test”

Key Matrix

Key matrix in XHYPER270TKU 4X4 Key matrix

Key 입력의 검출 4 inputs & 4 outputs Input 1 to keyout0, and 0 to others Make a loop to scan all keys  find one with keyoutX and keyinX 1 All outputs are 0 Only 1 key will be 1

Key scan driver fpga_device/key/key.c void Print_Key(int out , int in){     switch(out){         case 1:                        if(in == 1)     { dbg("key 4 is pressed\n");    key_data = 4;}                 else if(in == 2){ dbg("key 8 is pressed\n");    key_data = 8;}                 else if(in == 4){ dbg("key 12 is pressed\n");   key_data = 12;}                 else if(in == 8){ dbg("key 16 is pressed\n");   key_data = 16;}                 break;         case 2:                         if(in == 1)     { dbg("key 3 is pressed\n");    key_data = 3;}                 else if(in == 2){ dbg("key 7 is pressed\n");    key_data = 7;}                 else if(in == 4){ dbg("key 11 is pressed\n");   key_data = 11;}                 else if(in == 8){ dbg("key 15 is pressed\n");   key_data = 15;}         case 3:                         if(in == 1)     { dbg("key 2 is pressed\n");    key_data = 2;}                 else if(in == 2){ dbg("key 6 is pressed\n");    key_data = 6;}                 else if(in == 4){ dbg("key 10 is pressed\n");   key_data = 10;}                 else if(in == 8){ dbg("key 14 is pressed\n");   key_data = 14;}         case 4:                         if(in == 1)     { dbg("key 1 is pressed\n");    key_data = 1;}                 else if(in == 2){ dbg("key 5 is pressed\n");    key_data = 5;}                 else if(in == 4){ dbg("key 9 is pressed\n");    key_data = 9;}                 else if(in == 8){ dbg("key 13 is pressed\n");   key_data = 13;}                 break;                        } }

Key scan driver /* FPGA KEY 0x16400000 //FPGA_KEY_OUT# KEYOUT_D[0:3] : X_D[0:3] 0x16800000 //FPGA_KEY_IN# KEYIN_D[0:3] : X_D[0:3] */ #define FPGA_KEY_OUT (0x11D00000) #define FPGA_KEY_IN (0x11E00000) // (*((volatile unsigned char *)(mem_base))) #define KEYOUT (*((volatile unsigned char *)(mem_key_out))) #define KEYIN (*((volatile unsigned char *)(mem_key_in)))

Key scan driver void key_timer_function(unsigned long ptr) { int in, out; KEYOUT = ((1 << (ptr-1)) & (0x0f)); out = ptr; in = KEYIN; if(in != 0) { Print_Key(out, in); mdelay(200); } init_add_timer(); } void init_add_timer(void) { ++n; if( n > SCAN_NUM) n = 1; init_timer(&key_timer_str); // timer pointer key_timer_str.function =&key_timer_function ; key_timer_str.data = (unsigned long)n; key_timer_str.expires = jiffies + (HZ/100); add_timer(&key_timer_str);

Key scan driver static int key_init(void) { …… mem_addr_out = FPGA_KEY_OUT; mem_addr_in = FPGA_KEY_IN; mem_len = 0x1000; mem_key_out = ioremap_nocache (mem_addr_out, mem_len); if(!mem_key_out) { printk(" Error mapping key_out memory\n"); return -EBUSY; } mem_key_in = ioremap_nocache (mem_addr_out, mem_len); if(!mem_key_in) { printk(" Error mapping key_in memory\n"); ……….

Device 생성 확인: ls –l /dev/key Module 적재 ☞ lsmod↲ ☞ rmmod key↲ ☞ insmod key.ko↲

Key test ☞ ./ key-test↲

Character LCD 타겟 시스템은 HD44780 LCD 컨트롤러 모듈을 사용 16문자씩 2라인으로 표시. 폰트는 5*7도트. 제어를 위한 2개의 제어 비트(RS, R/W’)와 데이터 비트(D0~D7)에 [표 11-5]의 명령어로 설정한 후 Enable 클록을 On/Off함으로써 문자형 LCD로 데이터를 전송

문자형 LCD 디바이스 드라이버 작성 문자형 LCD 디바이스 드라이버 프로그램 작성 001 #include <linux/module.h> …… 009 #include <asm/io.h> 010 011 #define CLCD_MAJOR 238 012 #define CLCD_NAME "CLCD" 013 014 #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))) 018 019 static void *mem_base_wr, *mem_base_rs; 020 static unsigned long mem_addr_wr, mem_addr_rs, mem_len; 021 022 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 } 033 034 static void string_out(char *str) 035 { 036 char *s; 037 int i=0; 038 039 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 }

문자형 LCD 디바이스 드라이버 작성 …… 062 ssize_t clcd_write (struct file *filp, const char *buf, size_t count, loff_t *f_pos) 063 { 064 char data[32]; 065 066 memset(data, 0 , 32); 067 copy_from_user(data, buf, count); 068 string_out(data); 069 return 0; 070 } 071 072 struct file_operations clcd_fops = { 073 .owner = THIS_MODULE, 074 .write = clcd_write, 075 .open = clcd_open, 076 .release = clcd_release, 077 }; 078 079 static int clcd_init(void) 080 { 081 int result; 082 083 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; 091 092 mem_base_wr = ioremap_nocache ( mem_addr_wr, mem_len); 097 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 } 106 107 static void clcd_exit(void) 108 { 109 unregister_chrdev(CLCD_MAJOR, CLCD_NAME); 110 iounmap(mem_base_wr); 111 iounmap(mem_base_rs); 112 } 113 114 MODULE_LICENSE("GPL"); 115 module_init(clcd_init); 116 module_exit(clcd_exit);

실습 11-4 문자형 LCD 디바이스 드라이버 작성 디바이스 드라이버 테스트 프로그램 작성(11/clcd/test_clcd.c) 01 #include <stdio.h> 02 #include <fcntl.h> 03 #include <stdlib.h> 04 #include <unistd.h> 05 06 static char lcdDev[] = "/dev/CLCD"; 07 static int lcdFd = -1; 08 09 #define MAXCHR 32 10 11 int main(int argc, char **argv) 12 { 13 int n; 14 char buf[MAXCHR]; 15 16 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 디바이스 드라이버 작성 문자 LCD 디바이스 드라이버 프로그램을 컴파일하기 위한 Makefile을 작성 디바이스 드라이버 모듈과 응용 프로그램을 컴파일 기존 디바이스 드라이버와 디바이스 파일을 테스트한 후 삭제 ① ② ③

문자형 LCD 디바이스 드라이버 작성 생성한 디바이스 드라이버와 응용 프로그램을 타겟 시스템으로 전송 디바이스 드라이버를 커널로 적재하고 필요한 디바이스 파일을 생성한 후 테스트 ① ② ③

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

도트 매트릭스 디바이스 드라이버 프로그램 작성 도트 매트릭스 디바이스 드라이버 작성 도트 매트릭스 디바이스 드라이버 프로그램 작성 001 #include <linux/module.h> …… 009 #include <asm/io.h> 010 011 012 #define DOT_MAJOR 232 013 #define DOT_NAME "DOT" 014 015 #define FPGA_DOT_COL_1 (0x11800000) 019 #define FPGA_DOT_COL_5 (0x11C00000) 020 021 static void *mem_dot_col1, *mem_dot_col2, *mem_dot_col3, *mem _dot_col4, *mem_dot_col5; 022 023 #define DOT_COL_1 (*((volatile unsigned char *) (mem_dot_col1))) 027 #define DOT_COL_5 (*((volatile unsigned char *) (mem_dot_col5))) 028 029 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; 044 045 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

도트 매트릭스 디바이스 드라이버 작성 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, unsigned int 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 } 081 082 struct file_operations dot_fops = { 083 .owner = THIS_MODULE, 084 .open = dot_open, 085 .ioctl = dot_ioctl, 086 .release = dot_release, 087 }; 088 089 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; 094 095 result = register_chrdev(DOT_MAJOR, DOT_NAME, &dot_fops);

도트 매트릭스 디바이스 드라이버 작성 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; 107 108 mem_dot_col1 = ioremap_nocache ( mem_addr_col1, mem_len); 131 mem_dot_col5 = ioremap_nocache ( mem_addr_col5, mem_len); 136 137 printk("FPGA %s, MAJOR %d\n", DOT_NAME, result); 138 return 0; 139 } 140 141 static void dot_exit(void) 142 { 143 unregister_chrdev(DOT_MAJOR, DOT_NAME); 144 iounmap(mem_dot_col1); 148 iounmap(mem_dot_col5); 149 } 150 151 MODULE_LICENSE("GPL"); 152 module_init(dot_init); 153 module_exit(dot_exit);

도트 매트릭스 디바이스 테스트 프로그램 작성 도트 매트릭스 디바이스 드라이버 작성 01 #include <stdio.h> 02 #include <fcntl.h> 03 #include <sys/ioctl.h> 04 05 static char dotDev[] = "/dev/DOT"; 06 static int dotFd = -1; 07 08 int main() 09 { 10 dotFd = open(dotDev, O_RDWR ); 11 12 if ( dotFd < 0 ) { 13 fprintf(stderr, "cannot open DOT (%d)", dotFd); 14 exit(2); 15 } 16 17 ioctl(dotFd, 1, 0); 18 return 0; 19 }

도트 매트릭스 디바이스 드라이버 작성 도트 디바이스 프로그램 컴파일하기 위한 Makefile을 작성 디바이스 드라이버 모듈과 응용 프로그램을 컴파일 기존 디바이스 드라이버를 테스트한 후 디바이스 드라이버와 디바이스 파일을 삭제 ① ② ③

도트 매트릭스 디바이스 드라이버 작성 생성한 디바이스 파일과 응용프로그램을 타겟 시스템으로 전송 디바이스 드라이버를 커널로 적재하고 새로운 디바이스 파일을 만든 후 응용프로그램으로 테스트 ① ② ③