21
LED Device Driver 설설 설 설설

LED Device Driver 설계 및 응용

  • Upload
    linus

  • View
    128

  • Download
    9

Embed Size (px)

DESCRIPTION

LED Device Driver 설계 및 응용. LED 란 ?. 일반적으로 Light Emitting Diode ( 발광 다이오드 ) 의 약자로 불리며 순방향으로 전압을 가할 때 다이오드의 접합부에서 빛을 발생하는 다이오드 이다. LED 회로도. LED 제어. LED Port 주소 및 Data 입력 bit (PXA255 Pro). LED 제어. LED 의 제어 방법 (PXA255 Pro). LED 1 번을 ON 하는 예제 #define LED_IO_ADDR 0x0C000016 - PowerPoint PPT Presentation

Citation preview

Page 1: LED Device Driver  설계 및  응용

LED Device Driver 설계 및 응용

Page 2: LED Device Driver  설계 및  응용

일반적으로 Light Emitting Diode ( 발광 다이오드 ) 의 약자로 불리며 순방향으로 전압을 가할 때 다이오드의 접합부에서 빛을 발생하는 다이오드 이다 .

LED 란 ?

Page 3: LED Device Driver  설계 및  응용

LED 회로도

Page 4: LED Device Driver  설계 및  응용

LED Port 주소 및 Data 입력 bit (PXA255 Pro)

LED 제어

Bit 7 6 5 4 3 2 1 0

LED D8 D7 D6 D5 D4 D3 D2 D1

LED Port Physical Ad-dress

0x0C000016

Page 5: LED Device Driver  설계 및  응용

LED 의 제어 방법 (PXA255 Pro)

LED 제어

LED 1 번을 ON 하는 예제#define LED_IO_ADDR 0x0C000016*(LED_IO_ADDR) = 0xFE;

LED 제어LED On 해당 비트에 0 을 쓴다 .LED Off 해당 비트에 1 을 쓴다 .

Page 6: LED Device Driver  설계 및  응용

커널 2.4◦ 디바이스 드라이버의 사용 횟수를 자체에서 관리◦ 수행 매크로

MOD_INC_USE_COUNT 모듈 사용 횟수를 증가

MOD_DEC_USE_COUNT 모듈 사용 횟수를 감소

MOD_IN_USE 모듈 사용 횟수가 0 이 아니면 참

커널 2.6◦ 커널에서 디바이스 사용 횟수를 관리

모듈 사용 횟수 관리

Page 7: LED Device Driver  설계 및  응용

커널 2.4

int xxx_open (struct inode *inode, struct file *filp)

{

if(MOD_IN_USE) return –EBUSY;

MOD_INC_USE_COUNT;

return 0;

}

Int xxx_release (struct inode *inode, struct file *filp)

{

MOD_DEC_USE_COUNT;

return 0;

}

모듈 사용 횟수 관리

Page 8: LED Device Driver  설계 및  응용

함수◦ read 사용 함수

copy_to_user(to,from,n) 커널 메모리 from 을 사용자 메모리 to 로 n 만큼 복사

put_user(x,ptr) x 변수 값을 사용자 영역인 ptr 로 sizeof(ptr) 만큼 메모리에 복사

◦ write 사용 함수 copy_from_user(to,from,n)

사용자 메모리 from 을 커널 메모리 to 로 n 만큼 복사 get_user(x,prt)

x 변수 값에 사용자 영역인 ptr 의 값을 sizeof(ptr) 만큼 대입

읽기와 쓰기의 구현

Page 9: LED Device Driver  설계 및  응용

프로세서 입장에서 하드웨어의 I/O 는 시스템 마다 상이◦ I/O 맵드 입출력

메모리와 하드웨어 I/O 처리 방식이 다른 경우 I386 인텔 계열의 프로세스 in, out 이라는 별도의 명령이 존재

◦ 메모리 맵드 입출력 메모리와 하드웨어 I/O 처리 방식이 같은 경우 68 계열이나 ARM 계열

◦ ARM 이나 68 계열의 프로세서에서 동작하는 리눅스 커널에서는 inb(), outb() 같은 I/O 맵드 입출력 함수는 불필요 하지만 , 호환성 때문에 사용 메모리 맵드 입출력으로 맵핑 시켜줌

I/O 처리

Page 10: LED Device Driver  설계 및  응용

I/O 맵드 입출력 처리 함수◦ #include<asm/io.h>◦ 하드웨어에서 데이터를 읽기

unsigned char inb(unsigned short port); unsigned short inw(unsigned short port); unsigned long inl(unsigned short port); void insb(unsigned short port, void *addr, unsigned long

count); void insw(unsigned short port, void *addr, unsigned long

count); void insl(unsigned short port, void *addr, unsigned long

count)

I/O 처리

Page 11: LED Device Driver  설계 및  응용

I/O 맵드 입출력 처리 함수◦ 하드웨어에 데이터를 쓰기

void outb(unsigned char data, unsigned short port); void outw(unsigned short data, unsigned short port); void outl(unsigned long data, unsigned short port); void outsb(unsigned short port, void *addr, unsigned long

count); void outsw(unsigned short port, void *addr, unsigned long

count); void outsl(unsigned short port, void *addr, unsigned long

count);

I/O 처리

Page 12: LED Device Driver  설계 및  응용

물리 주소 공간을 커널 주소 공간으로 매핑◦ MMU(Memory Management Unit)

초기 리눅스의 프로세스간의 메모리 보호 장치가 없어 다른 프로세스의 공간을 침범하는 것을 막기 위해 사용

프로세스에서 전달되는 주소를 다른 주소로 변환 프로세서가 메모리에 접근하는 주소가 메모리에 직접 전달되는 것이 아니라 먼저

MMU 에 전달 MMU 는 변환 테이블을 참고해 이 주소를 실제 물리 주소로 변환하여 전달 프로세스는 MMU 에 가상 주소를 전달하며 , MMU 가 이 가상 주소를 해석하여

나온 물리주소를 실제 메모리에 전달◦ 주소 변환 함수

void *ioremap(unsigned long offset, unsinged long size); void *iounmap(void *addr);

메모리 매핑

Page 13: LED Device Driver  설계 및  응용

#include <linux/ioport.h>#include <asm/uaccess.h>#include <linux/module.h>#include <linux/fs.h>#include <asm/io.h>#include <linux/init.h>#include <linux/version.h>

#define IOM_LED_MAJOR 240 //ioboard led device major number#define IOM_LED_NAME "LEDS" //ioboard led device name#define IOM_LED_ADDRESS 0xC000016 // pysical address#define IOM_LED_ADDRESS_RANGE 1 // address range

//Global variablestatic int ledport_major = 0;static unsigned short *iom_led_addr;

led_driver.c

Page 14: LED Device Driver  설계 및  응용

// define functions...ssize_t iom_led_write(struct file *inode, const char *gdata, size_t length, loff_t

*off_what);int iom_led_open(struct inode *minode, struct file *mfile);int iom_led_release(struct inode *minode, struct file *mfile);

// define file_operations structure struct file_operations iom_led_fops ={

open: iom_led_open,write: iom_led_write,release: iom_led_release,

};

// when led device open ,call this functionint iom_led_open(struct inode *minode, struct file *mfile) {

if(MOD_IN_USE) return -EBUSY;MOD_INC_USE_COUNT;return 0;

}

led_driver.c

Page 15: LED Device Driver  설계 및  응용

// when led device close ,call this functionint iom_led_release(struct inode *minode, struct file *mfile) {

MOD_DEC_USE_COUNT;return 0;

}

// when write to led device ,call this functionssize_t iom_led_write(struct file *inode, const char *gdata, size_t length, loff_t

*off_what) {

unsigned char value;const char *tmp = gdata;

copy_from_user(&value,tmp,length);outb(value,iom_led_addr);

return length;}

led_driver.c

Page 16: LED Device Driver  설계 및  응용

int init_module(void){

int result;

result = register_chrdev(IOM_LED_MAJOR,IOM_LED_NAME,&iom_led_fops);if(result < 0) {

printk(KERN_WARNING"Can't get any major\n");return result;

}ledport_major = IOM_LED_MAJOR;iom_led_addr = ioremap(IOM_LED_ADDRESS,0x01);printk("init module, %s major number : %d\n",IOM_LED_NAME,ledport_major);return 0;

}

void cleanup_module(void) {

iounmap(iom_led_addr);if(unregister_chrdev(ledport_major,IOM_LED_NAME))

printk(KERN_WARNING"%s DRIVER CLEANUP FALLED\n",IOM_LED_NAME);

}

led_driver.c

Page 17: LED Device Driver  설계 및  응용

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>

int main(int argc, char **argv){

int dev;unsigned char buff;

if(argc <= 1) {printf("please input the parameter! \n");printf("ex)./test_led 0xa1\n");printf("ex)./test_led a1\n");return -1;

}

test_led.c

Page 18: LED Device Driver  설계 및  응용

dev = open("/dev/LEDS", O_WRONLY);if (dev != -1){

if(argv[1][0] == '0' && (argv[1][1] =='x'||argv[1][1] == 'X'))buff = (unsigned char)strtol(&argv[1][2], NULL,16);

elsebuff = (unsigned char)strtol(&argv[1][0], NULL,16);

write(dev,&buff,1);

close(dev);}else{

printf( "Device Open ERROR!\n");exit(-1);

}return(0);

}

test_led.c

Page 19: LED Device Driver  설계 및  응용

INCLUDEDIR := /lect/linux-2.4.19-pro3_nlcd/include

CFLAGS := -D__KERNEL__ -I$(INCLUDEDIR) -Wall -O2 -DMODULE

CROSS_COMPILE := arm-linux-

CC=$(CROSS_COMPILE)gcc

all: led_driver test_led

led_driver:$(CC) $(CFLAGS) -c led_driver.c -o led_driver.o

test_led: $(CC) -o test_led test_led.c

clean:rm -f *.o rm -f test_led

Makefile

Page 20: LED Device Driver  설계 및  응용

Target 의 디바이스 드라이버 모듈을 생성하기 위해서는 컴파일 과정에서 Target 의 커널 정보가 필요◦ 따라서 , CD 에서 Target 의 커널 파일을 복사 해야 함

커널 파일 복사 순서◦ 1. CD 삽입 후 마운트 확인◦ 2. 커널 파일 복사

# cp /mnt/cdrom/Kernel/linux-2.4.19-pro3_nlcd.tar.gz

◦ 3. 커널 압축 해제 # tar zxvf linux-2.4.19-pro3_nlcd.tar.gz

커널 파일 복사

Page 21: LED Device Driver  설계 및  응용

1. Minicom 연결 2. nfs 를 통해 호스트에 있는 디렉토리 공유 및 파일 확인

◦ led_driver.o, test_led 3. 장치 특수 파일을 생성

◦ # mknod /dev/LEDS c 240 0 4. 디바이스 드라이버를 커널에 추가한다 .

◦ # insmod led_driver.o 5. 테스트 프로그램을 이용해 LED 를 제어해 본다 .

◦ # ./test_led [16 진수 unsigned char 데이터 ]◦ ex)./test_led 0xa5◦ ex)./test_led a5

프로그램 테스트 (@Target)