linux驱动---Input 输入子系统

时间:2021-10-19 23:34:45

1,哪些驱动设备使用驱动子系统更方便简单?

像按键,触摸屏,鼠标等输入设备我们可以采用input接口函数来实现设备驱动,那么采用input输入子系统有什么优点?其实一句话,采用input输入子系统可以使驱动程序变得异常简单。


2,input输入子系统的体系结构


主要包括三大体系结构

设备驱动层drivers,输入核心层input core,事件处理层handers,其中inputcore,handlers是由内核来实现的,程序员做的就是利用input core提供的接口函数来实现drivers,

这三层分别具体实现的功能:

设备驱动层:将底层硬件的输入转化为统一的事件形式,想输入内核层汇报。


输入内核层:为驱动层提供输入设备注册与操作的接口,如input_register_driver:

通知事件处理层对事件进行处理;

在/proc下产生相应的设备信息;

事件处理层:主要作用是和用户空间进行交互,我们知道linux在用户空间将所有设备当成文件来处理,在一般的驱动程序中都有提供fops接口,以及在/dev下生成相应

的设备文件节点,而在输入子系统中,这些工作由事件处理层来完成。


3,驱动的实现;

1,事件支持

set_bit(EV_KEY,butt_dev.evbit);

参数button_dev是struct input_dev类型,他有二个成员evbit事件类型和keybit按键类型(但并非只有二个),关于事件类型和按键类型如下表:

linux驱动---Input 输入子系统


比如我们要支持按键1的话需要以下二条语句:

set_bit(EV_KEY,button_dev.bit);

set_bit(BIN_1,button_dev.keybit);


2,注册:

当input设备子持了相应的事件之后,就可以将设备注册到内核 input_register_device(&button_dev);


3,报告事件与完成报告


当在底层发生了中断,用户空间是如何知道的,这就需要inputcore提供一定的上报接口函数,由于报告事件在中断函数中完成的,所以需要在开始处,注册设备中断

request_irq(BUTTON_IRQ,button_irq,0,"button",null);然后再中断处理函数中完成报告事件


tatic void button_interrupt(int irq,void *dummy,struct pt_regs *fp)
                                                                {
input_report_key(&button_dev,BTN_0,inb(BUTTON_PORT1));//报告事件
                                                                        input_sync(&button_dev);//完成报告
                                                                }
注释:inb(BUTTON_PORT1)用于读取按键1的状态,并报告给input core
           input_report_key():用于报告EV_KEY事件状态
           input_report_key():用于报告EV_REL事件状态
           input_report_key():用于报告EV_ABS事件状态


4,在按键服务子程序中上报事件


static void button_irq(int irq,void *dummy,struct pt_regs *fp)

{

 input_report_key(&button_dev,BIT_0,inb(BUTTON_PORT0);

 input_report_key(&button_dev,BIT_1,inb(BUTTON_PORT1);

input_sync(&button_dev);


}


static int __init button_init(void)

{

if(request_irq(BUTTON_IRQ,button_interrupt,0,"button",null)

return _EBUSY;

set_bit(EV_KEY,button_dev,evbit);

set_bit(BIT_0,button_dev.keybit);

set_bit(BIT_1,button_dev.keybit);

}