输入子系统的基本编程方法

来源:互联网 发布:算法的含义 编辑:程序博客网 时间:2024/06/07 09:32

步骤

一、 在xxx_probe() 或 __init xxx中:       struct input_dev *simple_input;    1. 构建input device       simple_input = input_allocate_device();    2. 初始化input device        __set_bit(EV_KEY, simple_input->evbit);        __set_bit(KEY_DOWN, simple_input->keybit);    3. 注册input device        ret = input_register_device(simple_input);    4. 初始化硬件,获取到数据,并交给上层去处理二、 xxx_irq( )在中断函数中:    1. 给用户层上报数据       int scancode = KEY_ESC;       input_event(simple_input, EV_KEY,  scancode , 0);       input_sync(simple_input); //表示同步,也表示上报结束 三、 用户空间读到的数据:统一的数据包    struct input_event {        struct timeval time; //时间戳        __u16 type; //数据类型        __u16 code;//具体数据是什么        __s32 value;//值是是什么    }event;   用户层读数据包:    read(fd, &event, sizeof(struct input_event));        if(event.type == EV_KEY)            if(event.code == KEY_ESC)                if(event.value){                }

实例:输入子系统的中断

驱动端:

#include <linux/init.h>#include <linux/module.h>#include <linux/input.h>#include <linux/interrupt.h>#include <linux/gpio.h>#include <mach/gpio.h>struct input_dev *simple_input;int irqno;irqreturn_t input_key_irq_handler(int irqno, void *dev_id){    printk("-------^_^   %s-----------\n", __FUNCTION__);       //区分是按下还是抬起    int value;    value = gpio_get_value(S5PV210_GPH0(0));    //获取当前中断值    //上报数据    if(value){        //抬起        printk("__KERNEL__ KEY_ESC up\n");        //参数1: 上报哪个设备数据  参数2:哪种数据类型   参数3: 具体是哪个数据  参数4:  值        input_event(simple_input, EV_KEY,  KEY_ESC,  0);        input_sync(simple_input); //表示同步,也表示上报结束    }else{        //按下            printk("__KERNEL__ KEY_ESC pressed\n");        input_event(simple_input, EV_KEY,  KEY_ESC,  1);        input_sync(simple_input); //表示同步,也表示上报结束    }    return IRQ_HANDLED;}static int __init simple_input_dev_init(void){    int ret;    /*        a, 构建input device        b, 初始化 input device        c, 注册input device        d, 初始化硬件,获取到数据,并交给上层去处理    */    simple_input = input_allocate_device();   //a, 构建input device    if(simple_input == NULL)    {        printk(KERN_ERR "input_allocate_device error\n");        return -ENOMEM;    }    //在sys目录中,供用户查看的信息    simple_input->name = "simple my input";       simple_input->phys= "linux/key/input";    simple_input->uniq = "we have 8 btn";    simple_input->id.bustype = BUS_HOST;    simple_input->id.vendor = 0x1111 ;    simple_input->id.product = 0x0008;    simple_input->id.version = 0x0003;    __set_bit(EV_KEY,simple_input->evbit);    //b.初始化 input device    //表示该input device能够产生按键数据    __set_bit(EV_KEY, simple_input->evbit);    //具体又是那些按键呢?如: KEY_DOWN, KEY_POWER, KEY_LEFT    __set_bit(KEY_DOWN, simple_input->keybit);    set_bit(KEY_ESC, simple_input->keybit);    #if 0            __set_bit(KEY_POWER, simple_input->keybit);            __set_bit(KEY_LEFT, simple_input->keybit);    #else            //(另一种方法) simple_input->keybit[ 116/32]  |=  1<<116%32               simple_input->keybit[BIT_WORD(KEY_POWER)] |= BIT_MASK(KEY_POWER);            simple_input->keybit[BIT_WORD(KEY_LEFT)] |= BIT_MASK(KEY_LEFT);    #endif    ret = input_register_device(simple_input);   //c.注册simple_input到内核层    if(ret != 0)    {        printk(KERN_ERR "input_register_device error\n");        goto err_free;    }    //d. 初始化硬件,获取到数据,并交给上层去处理    irqno = IRQ_EINT(0);    unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING;    ret = request_irq(irqno,input_key_irq_handler, flags, "key1_eint0", NULL);    if(ret != 0)    {        printk(KERN_ERR "request_irq error\n");        goto err_1;    }    return 0;err_1:    input_unregister_device(simple_input);err_free:    input_free_device(simple_input);    return ret;}static void __exit simple_input_dev_exit(void){    printk("-------^_^   %s-----------\n", __FUNCTION__);    free_irq(irqno, NULL);    input_unregister_device(simple_input);    input_free_device(simple_input);}module_init(simple_input_dev_init);module_exit(simple_input_dev_exit);MODULE_LICENSE("GPL");

测试端 test.c

#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <unistd.h>#include <sys/ioctl.h>#include <linux/input.h>int main(int argc, char *argv[]){    int fd;    int ret;    struct input_event event;    fd = open("/dev/event0", O_RDWR);    if(fd < 0)    {        perror("open");        exit(1);    }    while(1)    {        ret = read(fd, &event, sizeof(struct input_event));        if(ret < 0)        {            perror("read");            exit(1);        }        if(event.type == EV_KEY)        {            if(event.code == KEY_ESC)            {                if(event.value)                {                    printf("__APP__ KEY_ESC pressed\n");                }else                {                    printf("__APP__ KEY_ESC up\n");                }            }        }       }    close(fd);    return 0;}
0 0
原创粉丝点击