한국어
Linux Programming
 

키패드 드라이버

pjk 2014.02.12 09:41 조회 수 : 7227

커널에 드라이버는 포함되어 있는데
/dev 에 장치가 없는 경우
 
입력 디바이스 정보를 읽어 본다.
 
root@godori:~# cat /proc/bus/input/devices
I: Bus=0019 Vendor=dead Product=beef Version=0001
N: Name="s3c2410-buttons"
P: Phys=input/s3c2440_buttons0
S: Sysfs=/class/input/input0
U: Uniq=
H: Handlers=kbd event0 evbug
B: EV=3
B: KEY=3fc
 
I: Bus=0013 Vendor=dead Product=beef Version=0101
N: Name="s3c2410 TouchScreen"
P: Phys=
S: Sysfs=/class/input/input1
U: Uniq=
H: Handlers=mouse0 event1 ts0 evbug
B: EV=b
B: KEY=400 0 0 0 0 0 0 0 0 0 0
B: ABS=1000003
 
그리고 이벤트 드라이버 정보를 읽어온다.
 
root@godori:~# cat /sys/class/input/event0/dev
13:64
 
mknod
 
root@godori:~# mknod /dev/input/event0 c 13 64
mknod: /dev/input/event0: No such file or directory
root@godori:~# mkdir /dev/input
root@godori:~# mknod /dev/input/event0 c 13 64
 
hexdump로 확인
 
root@godori:~# hexdump /dev/input/event0
0000000 0952 0000 cae3 0006 0001 0002 0001 0000
0000010 0952 0000 cb6a 0006 0000 0000 0000 0000
0000020 0952 0000 3bc3 0009 0001 0002 0000 0000
0000030 0952 0000 3c44 0009 0000 0000 0000 0000
0000040 0953 0000 ca9f 0006 0001 0003 0001 0000
0000050 0953 0000 cb17 0006 0000 0000 0000 0000
0000060 0953 0000 3ba4 0009 0001 0003 0000 0000
0000070 0953 0000 3c18 0009 0000 0000 0000 0000
0000080 0954 0000 2110 0003 0001 0004 0001 0000
0000090 0954 0000 2169 0003 0000 0000 0000 0000
00000a0 0954 0000 2e44 0006 0001 0004 0000 0000
00000b0 0954 0000 2eae 0006 0000 0000 0000 0000
00000c0 0955 0000 e8a9 0001 0001 0005 0001 0000
00000d0 0955 0000 e924 0001 0000 0000 0000 0000
00000e0 0955 0000 5988 0004 0001 0005 0000 0000
00000f0 0955 0000 59f4 0004 0000 0000 0000 0000
0000100 0955 0000 e524 000c 0001 0006 0001 0000
0000110 0955 0000 e5a3 000c 0000 0000 0000 0000
0000120 0956 0000 b023 0000 0001 0006 0000 0000
0000130 0956 0000 b0ac 0000 0000 0000 0000 0000
0000140 0956 0000 9f71 0008 0001 0007 0001 0000
0000150 0956 0000 9fed 0008 0000 0000 0000 0000
0000160 0956 0000 ac86 000b 0001 0007 0000 0000
0000170 0956 0000 acf2 000b 0000 0000 0000 0000
0000180 0958 0000 1465 0000 0001 0008 0001 0000
0000190 0958 0000 14eb 0000 0000 0000 0000 0000
00001a0 0958 0000 210c 0003 0001 0008 0000 0000
00001b0 0958 0000 217b 0003 0000 0000 0000 0000
00001c0 0958 0000 aca3 000b 0001 0009 0001 0000
 
00001c0 0958 0000 aca3 000b 0001 0009 0001 0000
struct input_event{
    struct timval        time; //aca3 000b
    unsigned short      type; //0001
    unsigned short      code; //0009
    unsigned int       value; //0001 0000
};
...
 
 
키입력 예제
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>

#define EVENT_BUF_NUM 64

int             event_fd = -1;    /* the file descriptor for the device */

int main(int argc, char **argv)
{
    int             i;       
    size_t          read_bytes;        // 몇 bytes read했느냐
    struct input_event event_buf[EVENT_BUF_NUM];  // 몇개의 event까지 한꺼번에 읽느냐
    char           *device = "/dev/input/event0";
    
    // input device open
    if ((event_fd = open(device, O_RDONLY)) < 0)
    {
        printf("%s: open error", device);   
        exit(1);
    }
    
    while (1) 
    {
        // event발생을 EVENT_BUF_NUM 만큼 읽어들인다.
        read_bytes = read(event_fd, event_buf, (sizeof(struct input_event)*EVENT_BUF_NUM) );
        if( read_bytes < sizeof(struct input_event) )  
        {
            printf("%s: read error", device);
            exit(1);
        }
        
        // 읽은 event 갯수만큼 loop를 돈다.
        for( i=0; i<(read_bytes/sizeof(struct input_event)); i++ )
        {
            // 각 event 발생의 type에 따른 분기 처리
            switch( event_buf[i].type )
            {
            case EV_SYN:
                printf("---------------------------------------n");
                break;
            case EV_KEY:
                printf("Button code %d", event_buf[i].code);
                switch (event_buf[i].value)
                {
                case 1:
                    printf(": pressedn");
                    break;
                case 0:
                    printf(": releasedn");
                    break;
                default:
                    printf("Unknown: type %d, code %d, value %d",
                           event_buf[i].type, 
                           event_buf[i].code, 
                           event_buf[i].value);
                    break;
                }
                break;
            default:
                printf("Unknown: type %d, code %d, value %dn",
                       event_buf[i].type, 
                       event_buf[i].code, 
                       event_buf[i].value);
                break; 
            }
        }
    }
    
    close(event_fd);
    exit(0);
}

http://mydroid.egloos.com/3506718


아래는 input_event 구조체에 관한 설명
키보드, 마우스, 터치 스크린 등의 장치가 연결이 되면 입력 디바이스 드라이버에서 이벤트 드라이버로 처리가 됩니다.  

 이벤트 드라이버로 처리 되면서 가정 좋은 점은 장치를 신경 쓸 필요 없이 공통된 형식의 데이터를 사용자에게 제공해 주는 것이다.

 

struct input_event{
    struct timval        time; 
    unsigned short      type;
    unsigned short      code;
    unsigned int       value;
};

 

위의 input_event 구조체는 방금 전에 말한 공통된 데이터 형의 값입니다.

각각의 멤버 변수에 대해 알아 봅시다.

 

*  time

입력 이벤트가 발생한 시간 정보 입니다.

 

*  type

터치와 마우스란 입력장치는 사용자가 입력한 위치정보를 발생하는 장치입니다.

그러나 위치정보의 의미가 다릅니다. 터치는 절대값(ABS_X, ABS_Y ..._)의 위치정보를 제공하고, 마우스는 변화량의 위치정보(REL_X, REL_Y …)를 제공합니다.

 

터치는 터치의 입력범위가 정해져 있기 때문에 사용자가 입력(누르는)하는 곳의 값이 고정된 값이들어 옵니다.

 

하지만 마우스는 고정 위치 값이 존재하지 않고, 마우스를 움직일 때 얼마나(상대적 변화량)움직이는가에 대한 상대적 변화량과, 방향 정보를 제공합니다.

이렇게 다른 타입을 구분하기 위한 정보를 ‘type’ 멤버가 제공한다.

 

*  code

‘code’ 멤버는 입력정보는 세분화하는 분류다. 설명이 쉽지 않다. 예로 설명하자.

마우스는 입력정보가 여려가지다.

좌버튼, 우버튼, 위로휠, 아래로 휠, 좌로이동, 우로이동, 위로이동, 아래로 이동 등등 이런 입력정보를 구분하기 위한 멤버이다.

이런 세분화하는 분류는 ‘code’에 따라 다르게 분류됩니다.

 

 

*  value

‘value’ 멤버는 ‘code’ 멤버의 해당하는 입력 값이다. 역시 예로 설명하자.

마우스가 우로 이동한 입력이 발생한다면, ‘code’멤버에 우로이동이란 값과 함께 얼마나

우로 이동했는지에 대한 값(변화량)이 ‘value’멤버로 제공됩니다.

 

위 설명했듯이 input_event의 각각의 멤버 변수는 장치에 따라 의미하는 바가 다릅니다. 따라서 이벤트 디바이스 드라이버를 사용하는 사용자는 각 장치마다 input_event의 멤버 변수 값을 다르게 구별해야 하는 약간의 번거로움이 있는데 ixLib를 사용하시면 이런 문제가 깔끔히 해결됩니다.