강좌 & 팁
안녕하세요 판다 이우영입니다.
오늘부터는 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); |