linux input子系统
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Linux系统提供了input子系统,按键,触摸屏,鼠标等输入型设备都可以利用input接口函数来实现设备驱动。在输入子系统中主要有4个层次依次为:
a.设备驱动层,具体设备层次,主要处理硬件中断,读取输入时间和控制硬件
b.输入子系统核心,管理输入设备,事件接口
c.inputer_handler,管理设备的事件处理方法
d.应用层,提供应用界面
如下图所示:
首先在内核linux2.6.32/documentation/input-programming中有一个简单的例子如下:
#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 %d\n", button_irq);
return -EBUSY;
}
button_dev = input_allocate_device();//分配一个input设备结构体
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);
以上有几个重要函数分别用红色字体标出,通过struct input_dev *button_dev
申明button_dev为input结构后申请中断后input_allocate_device();分配一个input设备结构体,然后设置按键信息后将该input结构体注册到内核当有对应中断产生后则跳转到对应的中断处理函数中去处理。在中断函数里面则向输入子系统报告产生了按键事件然后通知接受者一个报告发送完毕。
在input.h中input_dev结构体如下:
struct input_dev {
const char *name;//名称
const char *phys;//设备在系统中的物理路径
const char *uniq;//设备唯一的标识符
struct input_id id;//设备ID
//以下为支持的事件
unsigned long evbit[BITS_TO_LONGS(EV_CNT)];
unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];
unsigned long relbit[BITS_TO_LONGS(REL_CNT)];
unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];
unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];
unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];
unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];
unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];