福冈咸鱼 发表于 2023-2-26 21:56:20

嵌入式Linux—输入子系统

输入系统

常见的输入设备有键盘、鼠标、遥控杆、书写板、触摸屏等等,用户通过这些输入设备与Linux系统进行数据交换。
内核中怎样表示一个输入设备

// include/linux/input.h
struct input_dev {
        const char *name;//设备名称
        const char *phys;//设备物理路径
        const char *uniq;//设备唯一标识码
        struct input_id id;

        unsigned long propbit;

        unsigned long evbit;   //支持什么类型的输入事件
        unsigned long keybit; //支持按键输入事件的话,支持哪些按键(键盘)
        unsigned long relbit; //支持相对位移事件的话,支持哪些
        unsigned long absbit;
        unsigned long mscbit;
        unsigned long ledbit;
        unsigned long sndbit;
        unsigned long ffbit;
        unsigned long swbit;
       
        .......
       
        };查看所有的输入设备:
ls /dev/input/* -l查看输入设备的信息:
cat /proc/bus/input/devices得到如下信息:
# cat /proc/bus/input/devices
I: Bus=0019 Vendor=0000 Product=0000 Version=0000
N: Name="20cc000.snvs:snvs-powerkey"
P: Phys=snvs-pwrkey/input0
S: Sysfs=/devices/soc0/soc/2000000.aips-bus/20cc000.snvs/20cc000.snvs:snvs-powerkey/input/input0
U: Uniq=
H: Handlers=kbd event0 evbug
B: PROP=0
B: EV=3
B: KEY=100000 0 0 0

I: Bus=0018 Vendor=dead Product=beef Version=28bb//设备ID(定义在input.h的struct input_id结构体)
N: Name="goodix-ts"      //名称
P: Phys=input/ts         //物理地址
S: Sysfs=/devices/virtual/input/input1//sys系统地址
U: Uniq=          //标识号(无)
H: Handlers=event1 evbug
B: PROP=2      //设备属性
B: EV=b          //支持何种输入事件
B: KEY=1c00 0 0 0 0 0 0 0 0 0 0   //设备具有的键
B: ABS=6e18000 0

I: Bus=0019 Vendor=0001 Product=0001 Version=0100
N: Name="gpio-keys"
P: Phys=gpio-keys/input0
S: Sysfs=/devices/soc0/gpio-keys/input/input2
U: Uniq=
H: Handlers=kbd event2 evbug
B: PROP=0
B: EV=3
B: KEY=cAPP可以获得什么数据

// include/linux/input.h
struct input_value {
        __u16 type;   //当前数据的事件类型
        __u16 code;   //当前事件类型下的哪一个事件
        __s32 value;//
};Type的内容:
// include/uapi/linux/input-event-codes.h
/*
* Event types
*/

#define EV_SYN                        0x00//同步事件
#define EV_KEY                        0x01//键盘事件
#define EV_REL                        0x02//相对位移事件
#define EV_ABS                        0x03//绝对位移事件
#define EV_MSC                        0x04
#define EV_SW                        0x05
#define EV_LED                        0x11
#define EV_SND                        0x12
#define EV_REP                        0x14
#define EV_FF                        0x15
#define EV_PWR                        0x16
#define EV_FF_STATUS                0x17
#define EV_MAX                        0x1f
#define EV_CNT                        (EV_MAX+1)code的内容(以EV_KEY举例)
// include/uapi/linux/input-event-codes.h
#define KEY_RESERVED                0
#define KEY_ESC                        1
#define KEY_1                        2
#define KEY_2                        3
#define KEY_3                        4
#define KEY_4                        5
#define KEY_5                        6
#define KEY_6                        7
#define KEY_7                        8
#define KEY_8                        9
#define KEY_9                        10
#define KEY_0                        11获取输入设备信息实例

两个ioctl的request参数说明(input.h)

request说明EVIOCGID返回输入设备IDEVIOCGBIT(ev,len)获取输入设备支持的事件类型列表ev值的说明:ev参数表示要获取的事件类型,它是一个整数值

[*]当ev=0,表示要获取输入设备支持的所有事件类型列表,包括键盘事件、鼠标事件、相对事件、绝对事件、事件同步、杂项事件等。
[*]当ev=1,表示要获取输入设备支持的键盘事件类型列表。
[*]当ev=2,表示要获取输入设备支持的相对事件类型列表。
EVIOCGBIT的iotcl调用说明:必须使用
len = ioctl(fd, EVIOCGBIT(0, sizeof(evbit)), evbit);   
//len是evbit的实际读取大小,如果单独使用sizeof(evbit)得到len,将发生段错误源码:

#include #include #include #include #include #include /* 用法:./get_input_info /dev/input/event0 */int main(int argc, char const **argv){        int fd;        struct input_id id;        int err;        unsigned char byte;        unsigned int evbit;        int i;        int bit;        unsigned int len;        char *ev_names[] = {                "EV_SYN ",                "EV_KEY ",                "EV_REL ",                "EV_ABS ",                "EV_MSC ",                "EV_SW        ",                "NULL ",                "NULL ",                "NULL ",                "NULL ",                "NULL ",                "NULL ",                "NULL ",                "NULL ",                "NULL ",                "NULL ",                "NULL ",                "EV_LED ",                "EV_SND ",                "NULL ",                "EV_REP ",                "EV_FF        ",                "EV_PWR ",        };        if(argc != 2)         {                printf("Usage: %s \n", argv);                return -1;        }        fd = open(argv, O_RDWR);        if(fd == -1)         {                printf("can not open %s\n", argv);                return -1;        }        err = ioctl(fd, EVIOCGID, &id);      //返回输入设备ID        if(err == 0)        {                printf("bustype = 0x%x\n", id.bustype );                printf("vendor        = 0x%x\n", id.vendor);                printf("product = 0x%x\n", id.product );                printf("version = 0x%x\n", id.version );        }        len = ioctl(fd, EVIOCGBIT(0,sizeof(evbit)), evbit);   //返回输入事件类型        printf("support ev type:\n");        for(i = 0;i < len;i++)        {                byte = ((unsigned char *)evbit);                for(bit = 0;bit < 8;bit++)                {                        if(byte & (1
页: [1]
查看完整版本: 嵌入式Linux—输入子系统