
강좌 & 팁
안녕하세요 판다 이우영입니다.
오늘부터는 IOCTL을 실제로 구현해 보고 동작을 확인해 보도록 하겠습니다.
그럼 시작하겠습니다.
1. IOCTL 헤더파일
먼저 응용프로그램과 디바이스 드라이버가 공통으로 사용할 헤더 파일을 만들겠습니다.
#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. 응용 프로그램
그럼 실제 응용프로그램을 만들어 보겠습니다.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/ioctl.h> #include <fcntl.h> #include <unistd.h> #include <sys/poll.h> #include "ioctl.h"
#define LED_TIME_MAX_DATA 3
int main() { int dev_int; int dev_ioctl; struct
pollfd Events[ 1];
int retval;
char buff[128];
ioctl_info info; int readcnt; int switch_num; int led_time_data[3] = {1000,500,3000}; int led_time_count = 0;
printf("poll program start\n");
dev_int = open("/dev/int_dev",O_RDWR); dev_ioctl = open("/dev/ioctl_dev",O_RDWR);
if(dev_int
< 0) { printf("err dev_int\n"); return
-1; } if(dev_ioctl
< 0) { printf("err dev_ioctl\n"); return
-1; }
printf("wait poll \n");
buff[0] = 0x0;
while(1) { memset(Events,
0, sizeof(Events)); Events[0].fd = dev_int; Events[0].events = POLLIN;
retval = poll((struct pollfd *)&Events, 1, 2000);
if(retval
< 0) { perror("poll error : "); exit(EXIT_FAILURE); }
if(retval
== 0) { //led
on,off printf("no wake up\n"); // write(dev_led,buff,1); continue; }
if(Events[0].revents & POLLERR) { printf("Device %d Error\n"); exit(EXIT_FAILURE); }
if(Events[0].revents & POLLIN) { printf("Interrupt \n"); read(dev_int,buff,1);
switch_num = buff[0]; switch(switch_num) { case
0: ioctl(dev_ioctl,LED_ON); break; case
1: ioctl(dev_ioctl,LED_OFF); break; case
2: led_time_count = (led_time_count
+ 1)%LED_TIME_MAX_DATA; info.buff[0] =
led_time_data[led_time_count]; info.size = 1; ioctl(dev_ioctl,LED_TIMER,&info); break; case
3: ioctl(dev_ioctl,GET_LED_TIME,&info);
printf("LED TIME = %d\n",info.buff[0]);
break; } } }
close(dev_int); close(dev_ioctl);
return
0; } |
보시면은 디바이스 드라이버를 2개를 작성했습니다.
하나는 인터럽트를 확인하는 디바이스 드라이버와 실제로 led를 제어하는 디바이스 드라이버 입니다.
지금까지 배워온것들을 사용을 해보기위해 이것저것 짜집기 했습니다.
(매우 비효율 적일 수 있습니다. 이것은 동작을 확인하기위한 코드일 뿐입니다!!!)
GPIO 핀 4개를 사용해서 아까 만들어 둔 ioctl 명령이 실행 되도록 해두었습니다.
그럼 오늘은 여기까지!!
다음시간에 두 디바이스를 만들어 보도록 하겠습니다.
그럼 다음시간에 만나요~