1 / 21

LED Device Driver 설계 및 응용

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

linus
Download Presentation

LED Device Driver 설계 및 응용

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. LED Device Driver 설계 및 응용

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

  3. LED 회로도

  4. LED 제어 • LED Port 주소 및 Data 입력 bit (PXA255 Pro)

  5. LED 제어 • LED의 제어 방법 (PXA255 Pro) LED 1번을 ON 하는 예제 #define LED_IO_ADDR 0x0C000016 *(LED_IO_ADDR) = 0xFE;

  6. 모듈 사용 횟수 관리 • 커널2.4 • 디바이스 드라이버의 사용 횟수를 자체에서 관리 • 수행 매크로 • MOD_INC_USE_COUNT • 모듈 사용 횟수를 증가 • MOD_DEC_USE_COUNT • 모듈 사용 횟수를 감소 • MOD_IN_USE • 모듈 사용 횟수가 0이 아니면 참 • 커널2.6 • 커널에서 디바이스 사용 횟수를 관리

  7. 모듈 사용 횟수 관리 • 커널2.4 intxxx_open (structinode *inode, struct file *filp) { if(MOD_IN_USE) return –EBUSY; MOD_INC_USE_COUNT; return 0; } Intxxx_release (structinode *inode, struct file *filp) { MOD_DEC_USE_COUNT; return 0; }

  8. 읽기와 쓰기의 구현 • 함수 • 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)만큼 대입

  9. I/O 처리 • 프로세서 입장에서 하드웨어의 I/O는 시스템 마다 상이 • I/O 맵드 입출력 • 메모리와 하드웨어 I/O 처리 방식이 다른 경우 • I386 인텔 계열의 프로세스 in, out 이라는 별도의 명령이 존재 • 메모리 맵드 입출력 • 메모리와 하드웨어 I/O 처리 방식이 같은 경우 • 68계열이나 ARM계열 • ARM이나 68계열의 프로세서에서 동작하는 리눅스커널에서는inb(), outb()같은 I/O 맵드 입출력 함수는 불필요 하지만, 호환성 때문에 사용 • 메모리 맵드 입출력으로 맵핑 시켜줌

  10. I/O 처리 • 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)

  11. I/O 처리 • 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);

  12. 메모리 매핑 • 물리 주소 공간을 커널 주소 공간으로 매핑 • MMU(Memory Management Unit) • 초기 리눅스의 프로세스간의 메모리 보호 장치가 없어 다른 프로세스의 공간을 침범하는 것을 막기 위해 사용 • 프로세스에서 전달되는 주소를 다른 주소로 변환 • 프로세서가 메모리에 접근하는 주소가 메모리에 직접 전달되는 것이 아니라 먼저 MMU에 전달 • MMU는 변환 테이블을 참고해 이 주소를 실제 물리 주소로 변환하여 전달 • 프로세스는 MMU에 가상 주소를 전달하며, MMU가 이 가상 주소를 해석하여 나온 물리주소를 실제 메모리에 전달 • 주소 변환 함수 • void *ioremap(unsigned long offset, unsinged long size); • void *iounmap(void *addr);

  13. led_driver.c #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 variable static intledport_major = 0; static unsigned short *iom_led_addr;

  14. led_driver.c // 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 function int iom_led_open(struct inode *minode, struct file *mfile) { if(MOD_IN_USE) return -EBUSY; MOD_INC_USE_COUNT; return 0; }

  15. led_driver.c // when led device close ,call this function intiom_led_release(structinode *minode, struct file *mfile) { MOD_DEC_USE_COUNT; return 0; } // when write to led device ,call this function ssize_tiom_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; }

  16. led_driver.c intinit_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); }

  17. test_led.c #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int main(intargc, char **argv) { intdev; 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; }

  18. test_led.c 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); else buff = (unsigned char)strtol(&argv[1][0], NULL,16); write(dev,&buff,1); close(dev); } else{ printf( "Device Open ERROR!\n"); exit(-1); } return(0); }

  19. Makefile 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_drivertest_led led_driver: $(CC) $(CFLAGS) -c led_driver.c -o led_driver.o test_led: $(CC) -o test_ledtest_led.c clean: rm -f *.o rm -f test_led

  20. 커널파일 복사 • Target의 디바이스 드라이버 모듈을 생성하기 위해서는 컴파일 과정에서 Target의 커널 정보가 필요 • 따라서, CD에서 Target의 커널 파일을 복사 해야 함 • 커널 파일 복사 순서 • 1. CD 삽입 후 마운트 확인 • 2. 커널 파일 복사 • # cp /mnt/cdrom/Kernel/linux-2.4.19-pro3_nlcd.tar.gz • 3. 커널 압축해제 • # tarzxvf linux-2.4.19-pro3_nlcd.tar.gz

  21. 프로그램 테스트 (@Target) • 1. Minicom연결 • 2. nfs를 통해 호스트에 있는 디렉토리공유 및 파일 확인 • led_driver.o, test_led • 3. 장치 특수 파일을 생성 • # mknod /dev/LEDS c 240 0 • 4. 디바이스 드라이버를 커널에 추가한다. • # insmodled_driver.o • 5. 테스트 프로그램을 이용해 LED를 제어해 본다. • # ./test_led [16진수 unsigned char 데이터] • ex)./test_led 0xa5 • ex)./test_led a5

More Related