목록디바이스 드라이버 (12)
배우고픈 공돌이
1. 다중화 입출력을 사용해서 디바이스를 제어한다.2. 타이머 인터럽트로 5초마다 한 번씩 화면에 나타낸다. read 장치 13. 장치에 타이머 시간을 준다. write 장치 14. 지정 시간 후, 커널의 정보를 화면에 띄우며 종료한다. read 장치 2 #ifndef _SKELETON_H_#define_SKELETON_H_#define TIME_STEP(10 * HZ / 10) typedef struct{struct timer_list timer;unsigned long work;}__attribute((packed))KERNEL_TIMER_MANAGER; typedef struct {int pid;int next_fd;int f_flags;unsigned long start_code;unsigned ..
다양한 조건에서 프로세서가 깨어나도록 설정하는 것이 다중화 입출력이다. 여기서 조건이란 인터럽트뿐만 아니라 read, write, ioctl 등의 event을 말한다. 이 조건에 따라 프로세스가 살면 선택하는 event를 찾아 실행을하는데, 선택하기 위한 키를 poll이라한다. 블럭킹과의 차이 블럭킹은 단일 조건(인터럽트)으로 프로세스를 중간에 재우거나 깨운다. 다중화의 경우는 큰틀에서 디바이스 드라이버의 프로세스를 재우고 이벤트가 발생하면 프로세스가 일어난다. 유형 1. 한 디라이버에서 다중 Event 조건 때, poll 사용 유형 2. 여러 드라이버에서 Event 조건 때, poll 사용 소스 D/D #include #include #include #include #include #include #i..
인터럽트와는 다르게 지속적으로 io를 감시할 때, 워크 큐를 사용한다. *센싱장치 중에서 간헐적으로 얻는게 아닌 항상 감지가 필요한 키 매트릭스 등에 사용하는 기법이다. 사용할 때, 타이머를 사용하면 좋겠지만 그보다 더 빠른 처리, 큰 데이터 처리가 요구되면 워크큐를 생각할 수 있다. 예를 들어 블럭킹 코드를 생각해보자. ISR 안의 프로세스를 깨우는 동작이 실행되면 디바이스 READ에서 동작을 처리한다. 여기서, ISR의 데이터 처리량이 많아진다면(길어진다면) 그만큼 효율이 떨어진다. 이를 분산하고, 보조하기 위한 장치가 work queue이다. ISR에서 신호의 값만 추출한 후, 그 신호를 분석하기 위해 work queue를 놓고 READ를 실행하면 이상적일 것이다. *ISR만 놓는다면, 후에 들어온..
센서를 읽는 프로세스가 생성되었을 때, 그 센서의 신호가 비동기적으로(간헐적으로) 동작한다 가정한다.이 가정에서 계속 프로세스가 Run이 된다면 비효율적이다.그래서 인터럽트가 되기전에는 잠재우고, 인터럽트 발생 시에 wait queue에서 run queue로 이동시킨다면 효율적인 프로세싱이 된다. (*blocking은 멀티프로세싱(os), RTOS에서 의미가 있다.) 그렇기 위해서 필요한 헤더는 /linux/wait.h로 다음과 같은 타입의 wait queue를 생성해주어야한다. #include #include #include #include #include #include #include #include #include #include #include #include "skeleton.h"#includ..
아직 커널 인터럽트를 처리하기 위한 하드웨어 장치가 도착하지 않았음으로 인터럽트를 타이머에 물려 처리하는 것으로 한다. *커널에서 인터럽트 처리를 하기 위한 과정 * 프로세서에서의 인터럽트 컨트롤러 정보 ( intel의 pxa270프로세서 / 삼성 exynose 4412 ) *우분투의 interrupt 정보 /proc/interrupts *소스#include #include #include #include #include #include #include #include #include #include #include #include "skeleton.h" #define SK_IRQ 7#define SK_MAJOR240 int result;static KERNEL_TIMER_MANAGER *ptrmng =..
skeleton.h #ifndef _SKELETON_H_#define _SKELETON_H_ #define TIME_STEP (10*HZ / 10) typedef struct{struct timer_list timer;unsigned long work;}__attribute((packed))KERNEL_TIMER_MANAGER; void kerneltimer_register(KERNEL_TIMER_MANAGER *ptr,unsigned long time_over);void kerneltimer_timeover(unsigned long time_over); #endif skeleton.c #include #include #include #include #include #include #include #in..
#include #include #include #include #include #include #include #include #define SK_MAJOR240int result; /* minor1*/static int minor1_open(struct inode *inode, struct file *filp){printk("minor1 open success!\n");return 0;} static int minor1_release(struct inode *inode, struct file *filp){printk("minor1 release success!\n");return 0;} static ssize_t minor1_read(struct file *filp, char * buf,size_t ..
misc 장치에 레지스터 등록을 사용하면 모듈이 인스톨될 때, 자동으로 장치가 만들어진다. struct file_operations sk_fops ={ .owner = THIS_MODULE, .open = sk_open, .release = sk_release, .read = sk_read, .write = sk_write, .unlocked_ioctl = sk_ioctl,}; struct miscdevice sk_misc ={ .minor = MISC_DYNAMIC_MINOR, .name = "skeleton", .fops = &sk_fops,}; //#insmod skeleton.ko
application에서 장치를 open하는데까지의 순서 1. D/D 제작 2. 컴파일 위한 Makefile 제작 3. #make -> xxxx.ko 4. D/D 커널에 등록 #insmod xxxx.ko 5. 장치 파일 생성 #mknod /dev/xxxx c 245 1 c : character 장치 (장치 타입) 245 : major 번호 - 커널이 관리 1 : minor 번호 - D/D가 관리 6. APP에서 장치 파일을 OPEN할 수 있다. -체크 사항#lsmod | grep xxxx모듈 적재 확인#dmesgprintk 확인#cat /proc/devices커널 등록 확인#cat /proc/kallsyms커널의 심볼(모듈의 심볼) 확인#cat /proc/modules모듈의 정보를 확인#ls -a /de..