input 子系统(一) input demo

版权声明:本文为博主原创文章,任何组织或者个人可以在任何媒介上发表或转载我的文章、图片等.且转载后必须注明出处和邮箱,博客地址(https://blog.csdn.net/u011011827),本人邮箱([email protected]) https://blog.csdn.net/u011011827/article/details/87889717
  • 关于怎么用input api 写驱动,参见创建输入设备驱动程序,实例参考 下面的demo
  • 关于怎么在用户空间监听 input 事件,参见下面的demo

本篇提供了input内核驱动demo和用户空间监听程序demo

demo

  • 内核驱动程序

驱动makefile 请参考驱动makefile


// insmod input_demo_driver.ko
// 注意:此时会生成/dev/input/eventX // X 为 0  1 2 3
// 如果没有生成,请研究 busybox中 mdev 或者 udev
// input_demo_driver.c

#include <linux/module.h>
#include <linux/input.h>
#include <linux/hrtimer.h>

/**
  参考:
  输入子系统的写法demo https://www.kernel.org/doc/html/latest/input/input-programming.html
  输入子系统的函数api:https://www.kernel.org/doc/html/latest/driver-api/input.html
  测试:cat /proc/bus/input/devices会发现注册的设备
 **/

static struct input_dev *button_dev;
static struct hrtimer vibe_timer;

#define value 2000 // 2000ms

enum hrtimer_restart  timer_func(struct hrtimer * timer){
    input_report_key(button_dev, KEY_POWER,1);
    input_report_key(button_dev, KEY_POWER,0);
    input_sync(button_dev);

    hrtimer_start(&vibe_timer,ktime_set(value / 1000, (value % 1000) * 1000000),HRTIMER_MODE_REL);
    //return HRTIMER_RESTART; // 重新开始
    return HRTIMER_NORESTART; // 结束
}


static int __init test_init(void)
{
    int error;
    button_dev = input_allocate_device();//分配输入设备内存,失败返回NULL
    if (!button_dev) {
        printk(KERN_ERR "button.c: Not enough memory\n");//如果分配失败,没有足够内存
        error = -ENOMEM;
        return error;
    }
    //输入设备名字
    button_dev->name="I am simplest input subsystem";
    //设置设备的坐标直接和屏幕坐标向对应
    set_bit(INPUT_PROP_DIRECT,button_dev->propbit);
    //输入设备时间类型为键盘事件
    set_bit(EV_KEY, button_dev->evbit);
    //输入设备的键盘掩码为:拥有POWER键
    set_bit(KEY_POWER,button_dev->keybit);

    //设置产品id
    button_dev->id.bustype=BUS_I8042;
    button_dev->id.vendor=0x1111;
    button_dev->id.product=0x2222;
    button_dev->id.version=0x5555;


    //将设备注册进输入子系统
    error = input_register_device(button_dev);
    if (error) {
        printk(KERN_ERR "button.c: Failed to register device\n");//注册失败
        input_free_device(button_dev);//释放内存
        return error;
    }

    hrtimer_init(&vibe_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
    vibe_timer.function = timer_func;
    hrtimer_start(&vibe_timer,ktime_set(value / 1000, (value % 1000) * 1000000),HRTIMER_MODE_REL);
    printk(KERN_DEBUG "OK,input subsystem inited!\n");
    printk("OK,input subsystem inited!\n");
    return 0;
}

static void __exit test_exit(void)
{
    input_unregister_device(button_dev);
    hrtimer_cancel(&vibe_timer);
}

module_init(test_init);
module_exit(test_exit);
MODULE_LICENSE("GPL");
  • 用户空间的用户监听程序
// input_app.c
// 使用方法 : ./input_app  /dev/input/eventX // X 为 0  1 2 3
// 注意: 在监听前上报的数据并不会被监听到


#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include <linux/input.h>

int main(int argc, const char *argv[])

{

    int fd;

    struct input_event env;

    int c = 0;

    int i;

    fd =open(argv[1],0666);

    if(fd<=0)

    {

        puts("open error");

        return -1;

    }

    while(1)

    {

        c=read(fd,&env,sizeof(struct input_event));

        if(c<0)

        {

            perror("read error");

            return -1;

        }
        printf("---------------------------event begin\n");
        printf("type:%d code:%d value:%d\n",

                env.type,

                env.code,

                env.value);
        printf("---------------------------event end\n");
    }

    return 0;

}


猜你喜欢

转载自blog.csdn.net/u011011827/article/details/87889717