분류 전체보기
-
디바이스 드라이버 / 인터럽트 처리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..
-
디바이스 드라이버 / 동적 메모리 할당Linux/Linux Device Driver 2020. 9. 1. 12:40
kmalloc() 연속된 물리 메모리를 연속된 가상 공간에 매핑하여 할당 받는다. GFP_KERNEL 플래그는 kmalloc() 함수에서 사용하는 대표적인 인자값으로 동적 메모리 할당이 항상 성공하도록 요구한다. 이 값으로 kmalloc() 함수를 사용하면 커널이 관리하는 메모리가 충분하지 않을 경우에는 디바이스 드라이버를 호출한 프로세스가 수행을 멈추고, 동적 메모리를 할당할 수 있는 상태가 될 때까지 잠든다. 그러다 다른 프로세스에서 메모리를 반환해 커널이 동적 메모리를 할당할 수 있는 상태가 되면 깨어난다. 그래서 kmalloc() 함수를 인터럽트 서비스에서 사용할 때는 이 값을 사용하면 안된다. GFP_ATOMIC 플래그를 사용하는 경우 슬립되지 않으므로 인터럽트 핸들러에서도 사용될 수 있다. v..