博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
浅析Linux Input 子系统
阅读量:4227 次
发布时间:2019-05-26

本文共 3253 字,大约阅读时间需要 10 分钟。

在android中,定时alarm功能是很常用的,现在来分析下怎么实现的,这里将采用自下而上的方式讲解。

输入子系统又叫input子系统。其构建非常灵活,只需要调用一些简单的函数,就可以将一个输入设备的功能呈现给应用程序。

Input子系统 主要有下面几个结构:

struct input_dev;         //表示一个输入设备,包含输入设备的一些相关信息(如支持的按键码,s设备的名称,设备支持的事件。)

        struct input_handler;         //表示对输入事件的具体处理。为输入设备的功能实现了一个接口。输入事件最终传递到handler处理。
        struct input_handle;         用来关联struct input_dev和struct input_handler

输入子系统由驱动层,输入子系统核心层(input core)和事件处理层(event handler) 3部分组成。一个输入事件,如键盘按键等通过驱动层-> 系统核心层->事件处理层->用户空间的顺序到达用户空间并传给应用程序使用。其中input core由内核源码下driver/input/input.c 及相关头文件实现。核心层对下提供了设备驱动的接口,对上提供了事件处理层的编程接口。输入子系统主要涉及上面三个结构体。

做linux驱动,一般用结构体来描述设备;我们需要做的是申请相应的结构体空间,然后填充相关结构体内成员;之后注册这个结构体;主要就这么三步;

1)  struct input_dev *input_dev;

2)input_dev = input_allocate_device();         //申请相应的结构体空间

        input_dev ->evbit[0] = 0xb;

        input_dev ->keybit[0xa] = 0x400;
        input_set_abs_params(input_dev, ABS_X, 0, 0x3FF, 0, 0);
        input_set_abs_params(input_dev, ABS_Y, 0, 0x3FF, 0, 0);
        input_set_abs_params(input_dev, ABS_PRESSURE, 0, 1, 0, 0);
        input_dev ->name = s3c2410ts_name;
        input_dev ->id.bustype = BUS_RS232;
        input_dev ->id.vendor = 0xDEAD;
        input_dev ->id.product = 0xBEEF;
        input_dev ->id.version = S3C2410TSVERSION;         //填充相关结构体内成员;

3)input_register_device(input_dev);        // 注册struct input_dev这个结构体

然后跟代码会发现注册input_dev,做了如下步骤;

input_register_device()

                -->input_attach_handler();
                        -->input_match_device();
                        -->handler->connect();

注册这个设备后,它回去找与它匹配的struct handler结构;找到之后调用struct handler的connect()方法;

简单的实例 

#include 
#include
#include
#include
#include
#include
#include
#include
#include
struct file_operations hello_fops = { .owner = THIS_MODULE }; static struct input_dev *button_dev; /*输入设备结构体*/ static irqreturn_t button_interrupt(int irq, void *dummy) /*中断处理函数*/ { input_report_key(button_dev, BTN_0, inb(BUTTON_PORT) & 1); /*向输入子系统报告产生按键事件*/ input_sync(button_dev); /*通知接收者,一个报告发送完毕*/ return IRQ_HANDLED; } static int __init button_init(void) /*加载函数*/ { int error; int result; dev = MKDEV (hello_major, hello_minor); result = register_chrdev_region (dev, number_of_devices, "hello"); if (result<0) { printk (KERN_WARNING "hello: can't get major number %d\n", hello_major); return result; } /* dynamic allocation */ cdev_init (cdev, &hello_fops); cdev->owner = THIS_MODULE; result = cdev_add (cdev, dev, 1); if (request_irq(BUTTON_IRQ, button_interrupt, 0, "button", NULL)) /*申请中断处理函数*/ { /*申请失败,则打印出错信息*/ printk(KERN_ERR "button.c: Can't allocate irq %d\n", button_ irq); return -EBUSY; } button_dev = input_allocate_device(); /*分配一个设备结构体*/ if (!button_dev) /*判断分配是否成功*/ { printk(KERN_ERR "button.c: Not enough memory\n"); error = -ENOMEM; goto err_free_irq; } button_dev->evbit[0] = BIT_MASK(EV_KEY); /*设置按键信息*/ button_dev->keybit[BIT_WORD(BTN_0)] = BIT_MASK(BTN_0); error = input_register_device(button_dev); /*注册一个输入设备*/ if (error) { printk(KERN_ERR "button.c: Failed to register device\n"); goto err_free_dev; } return 0; err_free_dev: /*以下是错误处理*/ input_free_device(button_dev); err_free_irq: free_irq(BUTTON_IRQ, button_interrupt); return error; } static void __exit button_exit(void) /*卸载函数*/ { input_unregister_device(button_dev); /*注销按键设备*/ free_irq(BUTTON_IRQ, button_interrupt); /*释放按键占用的中断线*/ } module_init(button_init); module_exit(button_exit);

转载地址:http://ghcqi.baihongyu.com/

你可能感兴趣的文章
[react-native]prop,state对比
查看>>
ssl问题被google 拒收
查看>>
[GreenDAO]like的坑
查看>>
正则表达式中的元字符
查看>>
Java Collection很好的介绍
查看>>
java中的JSon解析
查看>>
解决 Mybatis Generator由表字段使用关键字导致的异常方案
查看>>
HTTP请求的基础知识——HTTP中GET,POST和PUT的区别
查看>>
为什么需要Java反射?
查看>>
Java代码反编译——下载class字节码文件及反编译.class文件
查看>>
稀疏表示去噪的理解
查看>>
稀疏表示(二)——KSVD算法详解(结合代码和算法思路)
查看>>
剑指Offer习题集锦——Java实现及思路分析
查看>>
剑指Offer——二叉树镜像问题
查看>>
剑指Offer——二叉搜索树中第K大的节点
查看>>
剑指Offer——数据流中的中位数
查看>>
剑指Offer——查找队列中的最大值
查看>>
剑指Offer——顺时针遍历矩阵
查看>>
剑指Offer——栈的压入、弹出顺序
查看>>
剑指Offer——从上到下打印二叉树
查看>>