Linux/Linux Device Driver
-
디바이스 드라이버 / 디바이스의 제어Linux/Linux Device Driver 2020. 9. 1. 22:55
하드웨어에 데이터를 써넣을 때는 write() 함수를, 반대로 하드웨어에서 발생한 데이터를 읽을 때는 read() 함수를 이용한다. 하지만 read와 write만으로 하드웨어를 제어할 수 없는 경우도 종종 발생한다. 그래서 리눅스 커널은 ioctl이라는 방식을 제공한다. ioctl() 함수는 디바이스 파일 이외에는 사용할 수 없는 디바이스 파일 전용 함수이므로 각 디바이스다마다 고유하게 선언하여 사용한다. 그래서 read()함수와 write() 함수 같이 정형화된 형태를 기본적으로 유지하지만 사용 방법은 다비아스마다 모두 다르다. 개념적인 xxx_ioctl 구성 static long xxx_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { ..
-
디바이스 드라이버 / 인터럽트 처리Linux/Linux Device Driver 2020. 9. 1. 12:46
/dev/mem 등 디바이스 파일을 이용하면 root 권한을 갖는 응용 프로그램에서도 하드웨어를 제어할 수 있지만, 인터럽트 만큼은 디바이스 드라이버를 이용해야 한다. 인터럽트 서비스 함수의 형식 #include // 커널 디렉터리/include/linux/interrupt.h irqreturn_t (*irq_handler_t)(int, void *) // 인터럽트 서비스 함수 인터럽트 서비스 함수의 반환값 #include // 커널 디렉터리/include/linux/irqreturn.h enum irqreturn{ IRQ_NONE // intterupt was not from this device or was not handled IRQ_HANDLED // interrupt was handled by ..
-
디바이스 드라이버 / 시간 처리와 커널 타이머Linux/Linux Device Driver 2020. 9. 1. 12:45
디바이스 드라이버를 작성하다 보면 시간에 따른 여러 가지 처리가 필요하다. 커널은 이런 시간에 따른 처리를 하기 위해 jiffies라는 전역 변수를 여러 시간의 기준이 되는 시간값으로 사용하고 있다. 디바이스 드라이버는 이 기준값을 이용하여 상대적인 시간의 흐름을 측정하고, 그에 따라 하드웨어를 제어하게 된다. HZ: 1초당 발생되는 타이머 인터럽트 횟수 USER_HZ: HZ값을 보정하는 수 jiffies: 초당 HZ 만큼 증가하는 전역 변수 jiffies_64: 초당 HZ 만큼 증가하는 전역 변수 get_giffies_64(): jiffies_64를 참조하기 위한 함수 #include : 커널 디렉터리/include/linux/jiffies.h u64 get_jiffies_64(void) +#inclu..
-
디바이스 드라이버 / LED 제어Linux/Linux Device Driver 2020. 9. 1. 12:44
디바이스 드라이버로 하드웨어를 제어하기 전에 응용프로그램에서 하드웨어를 제어하여 LED를 출력해보자. 응용프로그램에서 GPIO를 제어하여 LED를 제어하는 방법 첫 번째 방법은 wiringPi 라이브러리를 이용하는 방법이다. 몇 번핀을 쓸 것인지만 정하고 적절한 함수에 해당 핀 번호를 매개변수로 넘겨주면 알아서 제어가 된다. 실제로 핀 설정하기전에 wiringPiSetup()이라는 함수가 수행되는데 이 함수를 보면 세 번째 방법에서 수행하는 GPIO를 제어할 수 있는 메모리 영역을 mmap함수(매핑)를 수행한다. wiringPi 라이브러리를 사용하여 생각할게 없고 쉽다. 하지만 공부에는 전혀 도움이 안돼서 안 썼다.매핑도 직접해봐야 공부가 된다. 두 번째 방법은 /sys/class/gpio를 이용하는 방..
-
디바이스 드라이버 / 부 번호에 의한 파일 처리Linux/Linux Device Driver 2020. 9. 1. 12:41
부 번호에 의한 파일 처리는 register_chrdev() 함수를 사용해야 합니다. 그럼 register_chrdev() 함수를 사용하는 이유는 뭘까요? 바로 부 번호로 제어를 하기 위해서는 디바이스 파일과 1:N으로 대응해야 하기 때문입니다. pi@raspberrypi:~/Documents/minor $ nano minor_driver.c #include #include #include #include // file_operations 포인터 함수 #include // copy_to_user() #include // kmalloc() #define MAJOR_DEV_NAME "major_dev" #define MAJOR_DEV_NUM 200 static int minor1_open(struct ino..
-
디바이스 드라이버 / 주 번호에 의한 파일 처리Linux/Linux Device Driver 2020. 9. 1. 12:41
주 번호에 의한 파일 처리는 register_chrdev()와 register_chrdev_region() 두 가지 함수를 사용할 수 있습니다. pi@raspberrypi:~/Documents/major $ nano major_driver.c #include #include #include #include // file_operations #include // copy_to_user() #include // kmalloc() #define MAJOR_DEV_NAME"major_dev" #define MAJOR_DEV_NUM200 static int major_open(struct inode *inode, struct file *file) { printk("major_open\n"); return 0; }..
-
디바이스 드라이버 / 메모리 풀Linux/Linux Device Driver 2020. 9. 1. 12:40
pi@raspberrypi:~/Documents/mempool $ nano mempool.c #include #include #include #include #include #define MIN_ELEMENT 2; #define TEST_ELEMENT 4; typedef struct { int number; char string[128]; }TMemElement; int elementcount = 0; void* mempool_alloc_test(unsigned int gfp_mask, void* pool_data) { TMemElement* data; printk("----> call mempool_alloc_test\n"); data = kmalloc(sizeof(TMemElement), gfp_ma..