panda.jpg 


안녕하세요 판다 이우영입니다.


오늘부터는 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 명령이 실행 되도록 해두었습니다.


그럼 오늘은 여기까지!!


다음시간에 두 디바이스를 만들어 보도록 하겠습니다.


그럼 다음시간에 만나요~