강좌 & 팁
안녕하세요 판다 이우영입니다.
저번 시간에 이어서 IOCTL 디바이스 드라이버를 구현해 보겠습니다.
1. 복습!!
디바이스 드라이버에서도 전에 만들어둔 해더 파일을 사용하기 때문에 다시 한번 확인하고 넘어가겠습니다.
#ifndef _IOCTL_H_ #define _IOCTL_H_
typedef struct { unsigned long size; unsigned int buff[128]; } __attribute__((packed)) ioctl_info;
#define IOCTL_MAGIC 'g' #define LED_ON _IO( IOCTL_MAGIC, 0) #define LED_OFF _IO( IOCTL_MAGIC, 1) #define LED_TIMER _IOW( IOCTL_MAGIC, 2 , ioctl_info ) #define GET_LED_TIME _IOR( IOCTL_MAGIC, 3 , ioctl_info )
#define IOCTL_MAXNR 4 #endif // _IOCTL_H_ |
위에 보시면 사용할 명령어들이 있습니다.
매직 넘버는 “g”를 사용하며 LED를 제어하기 위하여 “LED_ON”과 “LED_OFF”명령어를 만들고,
“LED_TIMER” 명령어를 사용하며 시간 주기마다 LED를 점멸시키기 위해 만들었습니다.
“GET_LED_TIME” 명령어는 타이머 시간 주기 값을 읽어 옵니다.
2. IOCTL 디바이스 드라이버
IOCTL을 사용하는 디바이스 드라이버 부터 보겠습니다.
#include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h>
#include <linux/version.h> #include <linux/fs.h> #include <linux/sched.h>
#include <linux/interrupt.h> #include <linux/wait.h> #include <linux/irq.h>
#include <linux/ioport.h> #include <linux/slab.h> #include <linux/poll.h> #include <linux/proc_fs.h> #include <linux/workqueue.h>
#include <linux/time.h> #include <linux/timer.h>
#include <linux/poll.h>
#include <asm/system.h> #include <asm/uaccess.h> #include <asm/ioctl.h> #include <asm/unistd.h> #include <asm/io.h> #include <asm/irq.h> #include <asm/gpio.h> #include <asm/mach/arch.h>
#include <plat/gpio-cfg.h> #include "ioctl-gpio-int.h" #include "ioctl.h"
#define IOCTL_DEV_NAME "dev_ioctl"
#define IOCTL_DEV_MAJOR 241
#define TIME_STEP (HZ*2)
#define LED_GPIO_DATA_REGISTER 0x7F008184 #define LED0 (1<<2) #define LED1 (1<<3) #define LED2 (1<<4) #define LED ((1<<2)|(1<<3)|(1<<4)) #define PAGE_SIZES 0x1000 #define DATA_SIZE 0x1000
u32 led_time;
DECLARE_WAIT_QUEUE_HEAD(
WaitQueue_Read );
typedef struct { struct
timer_list timer; unsigned
long led; u8 flag; }
__attribute__
((packed)) KERNEL_TIMER_MANAGER;
KERNEL_TIMER_MANAGER *ptrmng =
NULL; static unsigned
int ReadQ_timet_Count = 0; volatile u32 *led_data;
void kerneltimer_led(unsigned
long arg);
void kerneltimer_registertimer(KERNEL_TIMER_MANAGER *pdata, unsigned long timeover) { init_timer(&(pdata->timer)); pdata->timer.expires =
get_jiffies_64( ) + timeover; pdata->timer.data = (unsigned long) pdata; |