panda.jpg


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


오늘은 저번 시간에 이어서 POLL 공부를 해보겠습니다.


오늘도 복습 먼저!!


1. 복습!!!




저번 시간에는 POLL을 사용하기 위해서 디바이스 드라이버를 


어떤식으로 작성해야하는지 알아 보았습니다.


다시한번 확인해 볼까요?


POLL을 사용하기 위해서는 file_operations 구조체에 다음과 같이 xxx_poll() 함수를 등록해야 합니다.


struct file_operations kerneltimer_fops =

{

       .owner   = THIS_MODULE,

       .read    = kerneltimer_read,

       .write   = kerneltimer_write,

       .poll    = kerneltimer_poll,

       .open    = kerneltimer_open,

       .release = kerneltimer_release,

};


등록을 하기위해서는 함수가 구현 되어 있어야 겠죠?


함수는 아래와 같은 형태로 구성 됩니다.


unsigned int XXX_poll(struct file *file, poll_table *wait);


간단한 사용법은 다음과 같습니다.


DECLARE_WAIT_QUEUE_HEAD(WaitQueue_Read);


unsigned int XXX_poll( struct file *file, poll_tablr *wait)

{

int mask = 0;


poll_wait( file, &WaitQueue_Read, wait );

if( 쓰기 가능 ) mask |= (POLLIN POLLRDNORM );


return mask;

}


간단하게 복습을 하고 그럼 응용프로그램에서 해줘야 하는 일을 배워보도록 하겠습니다.


2. POLL을 사용하는 응용 프로그램




응용 프로그램도 어려운 작업은 없습니다.


다만 open한 여러 디바이스 장치를 등록해주면 됩니다.


등록해주는 구조체는 pollfd 입니다. 



struct pollfd 

{

int     fd; //파일 디스크립터 번호를 등록한다.

short events; //요구하는 이벤트

short revents; //반환된 이벤트

}



사용하기 위해서는 sys/poll.h 를 참조해주어야 합니다.


그럼 사용 얘제를 간단하게 작성해 보겠습니다.



#include <sys/poll.h>


int main( int argc, char **argv )

{

int  fd1,fd2;

int retval;

struct pollfd Events[2];


fd1 = open("디바이스1", O_RDWR | O_NOCTTY );

fd2 = open("디바이스2", O_RDWR | O_NOCTTY );


memset ( Events, 0 ,sizeof(Events) );


Events[0].fd = fd1;

Events[0].events = POLLIN | POLLERR;

Events[1].fd = fd2;

Events[1].events = POLLOUT;


while( 1 )

{

retval = poll( (struct pollfd *)&Events, 2, 5000);

if( retval < 0 )

printf("poll err\n");

else if( 0 == retval )

printf("No event!!\n")l

else

{

if( POLLERREvents[0].revents )

printf("장치 에러\n");

else if( POLLIN & Events[0].revents )

{

read(fd1, ~,~);

}

else if (POLLOUT & Events[1].revents )

{

write(fd2, ~, ~);

}

}

}


close(fd1);

close(fd2);

}



소스 코드를 보시고 알 수있을까요?


음 간단한 설명 들어갑니다.


일단 위에 보시는거와 같이 사용할 디바이스 장치를 open 해줍니다.


그리고 open 한 디바이스의 디스크립터 번호를 pollfd 구조체에 등록해줍니다.


여기가 중요한곳입니다. events 는 장치에서 어떤 이벤트가 발생했을 때 poll에게 알려줄지를 설정하는 부분입니다.


0번 Events에는 IN과 ERR 일 경우에 1번 Events에는 OUT일 경우 알려달라고 등록했습니다.


그리고 나서 poll 을 통해 등록을 합니다. poll 함수는 다음과 같이 구성되어 있습니다.



int poll(struct pollfd *ufds, unsigned int nfds, int timeout );



첫번째 인자는 우리가 만들어준 pollfd 구조체를 등록해 줍니다.


두번째 인자는 몇개의 디바이스 장치를 사용하는지 알려줍니다.

(pollfd에 10개를 등록하더라도 여기에 2개만 적어두면 2~9번 디바이스에 대한 응답은 오지 않습니다.)


세번째 인자는 기다려줄 시간을 적어줍니다.

(무한정 기다릴 수는 없자나요?)


poll 함수는 우리가 등록해준 pollfd의 events 부분에 해당하는 이벤트가 발생하면 발생한 이벤트의 수를 반환하여 알려줍니다.


만약 정해진 시간동안 이벤트가 없었다면 0을 반환합니다.


여기도 중요한 부분입니다. 이벤트가 발생한건 알지만 어느 장치에 어떤 이벤트가 발생했는지 알 수가 없습니다.


그래서 pollfd의 revents가 있는 겁니다.


여기에는 디바이스 드라이버의 poll에서 발생한 이벤트를 등록해 줍니다.

(저번시간에 등록했었죠? 기억해 보세요)


그럼 우리는 이 revents를 확인하여 어떤 장치에서 이벤트가 발생했는지를 알 수 있고 그에 따른 동작을 하게 만들어 줍니다.



오늘은 여기까지!!!  


응용프로그램에서 어떤식으로 작성해주어야 하는지 알아 보았습니다.


그럼 다음시간에 만나도록 하겠습니다.


바이바이~~