Linux 的输入子系统不仅支持鼠标、键盘等常规输入设备,而且还支持蜂鸣器、触摸屏等设备。本章将对 Linux 输
入子系统进行详细的分析。
一 前言
输入子系统又叫 input 子系统。其构建非常灵活,只需要调用一些简单的函数,就可以将一个输入设备的功能呈现
给应用程序。
二 设备驱动层
本节将讲述一个简单的输入设备驱动实例。
这个输入设备只有一个按键,按键被连接到一条中断线上,当按键被按下时,将产生一个中断,内核将检测到这个中断,并对其进行处理。该实例的代码如下:
#include
#include
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; if (request_irq(BUTTON_IRQ, button_interrupt, 0, "button", NULL)) /*申请中断,绑定中断处理函数*/ { printk(KERN_ERR "button.c: Can't allocate irq %dn", button_irq); return -EBUSY; }
button_dev = input_allocate_device(); /*分配一个设备结构体*/
//input_allocate_device()函数在内存中为输入设备结构体分配一个空间,并对其主要的成员进行了初始化.
if (!button_dev)
{ printk(KERN_ERR "button.c: Not enough memoryn"); 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);
//分别用来设置设备所产生的事件以及上报的按键值。Struct iput_dev中有两个成员,一个是evbit.一个是keybit.分别用
//表示设备所支持的动作和键值。
error = input_register_device(button_dev); /*注册一个输入设备*/ if (error)
{ printk(KERN_ERR "button.c: Failed to register devicen"); 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);
这个实例程序代码比较简单,在初始化函数 button_init()中注册了一个中断处理函数,然后调用
input_allocate_device()函数分配了一个 input_dev 结构体,并调用 input_register_device()函数对其进行了注册。在中
断处理函数 button_interrupt()中,实例将接收到的按键信息上报给 input 子系统。从而通过 input 子系统,向用户态程序
提供按键输入信息。本实例采用了中断方式,除了中断相关的代码外,实例中包含了一些 input 子系统提供的函数,现对
其中一些重要的函数进行分析。