没有合适的资源?快使用搜索试试~ 我知道了~
Linux_event层机制分析.pdf
需积分: 42 1 下载量 74 浏览量
2013-10-18
15:56:33
上传
评论
收藏 217KB PDF 举报
温馨提示
试读
12页
Linux_event层机制分析 前曾研究了一下输入子系统的原理,给人的感觉是输入子系统很复杂.但其实内核开发者在这方面已经做得很完善了, 输入子系统虽然错综复杂,但是只要我们领会了输入子系统的一些设计思想后,我们要使用它并非难事.
资源详情
资源评论
资源推荐
输入子系统--event 层分析
##############################################################
#######################################
早前曾研究了一下输入子系统的原理,给人的感觉是输入子系统很复杂.但其实内核开发者在这方面已经做得很完善了,
输入子系统虽然错综复杂,但是只要我们领会了输入子系统的一些设计思想后,我们要使用它并非难事.
以下以内核自带的 gpio_keys 驱动为例,介绍输入子系统的使用.
主要的原因是 gpio_keys 驱动比较简单易懂,另外不是没个人都有触摸屏,但键盘的话相信每一块开发板上都配有吧
^_^
按照以前的习惯,先从下到上的研究底层驱动是如何提交输入事件的:
##############################################################
#######################################
drivers/input/keyboard/gpio_keys.c:
static int __devinit gpio_keys_probe(struct platform_device *pdev)
{
struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
struct input_dev *input;
int i, error;
input = input_allocate_device();//申请 input_dev 结构
if (!input)
return -ENOMEM;
platform_set_drvdata(pdev, input);//把 input_dev 结构放好(以后方便调用)
input->evbit[0] = BIT(EV_KEY);//目前 event 的类型不操作 32,所以你会看到对于 evbit 数组的操作都是对
evbit[0]中的位来进行操作.
input->name = pdev->name;
input->phys = "gpio-keys/input0";
input->dev.parent = &pdev->dev;
input->id.bustype = BUS_HOST;
input->id.vendor = 0x0001;
input->id.product = 0x0001;
input->id.version = 0x0100;
for (i = 0; i < pdata->nbuttons; i++) {
struct gpio_keys_button *button = &pdata->buttons[i];
int irq = gpio_to_irq(button->gpio);
unsigned int type = button->type ?: EV_KEY;
set_irq_type(irq, IRQ_TYPE_EDGE_BOTH);
/* 根据用户所指定的 gpio_keys 来申请中断和注册中断处理函数*/
error = request_irq(irq, gpio_keys_isr, IRQF_SAMPLE_RANDOM,
button->desc ? button->desc : "gpio_keys",
pdev);
if (error) {
printk(KERN_ERR "gpio-keys: unable to claim irq %d; error %d\n",
irq, error);
goto fail;
}
input_set_capability(input, type, button->code);
}
error = input_register_device(input);//注册输入设备,并和对应的 handler 处理函数挂钩
if (error) {
printk(KERN_ERR "Unable to register gpio-keys input device\n");
goto fail;
}
return 0;
fail:
for (i = i - 1; i >= 0; i--)
free_irq(gpio_to_irq(pdata->buttons[i].gpio), pdev);
input_free_device(input);
return error;
}
提到 input_dev 结构,以下谈一下我对于它的理解:
struct input_dev {
void *private;
const char *name;
const char *phys;
const char *uniq;
struct input_id id;
/*
* 根据各种输入信号的类型来建立类型为 unsigned long 的数组,
* 数组的每 1bit 代表一种信号类型,
* 内核中会对其进行置位或清位操作来表示时间的发生和被处理.
*/
unsigned long evbit[NBITS(EV_MAX)];
unsigned long keybit[NBITS(KEY_MAX)];
unsigned long relbit[NBITS(REL_MAX)];
unsigned long absbit[NBITS(ABS_MAX)];
unsigned long mscbit[NBITS(MSC_MAX)];
unsigned long ledbit[NBITS(LED_MAX)];
unsigned long sndbit[NBITS(SND_MAX)];
unsigned long ffbit[NBITS(FF_MAX)];
unsigned long swbit[NBITS(SW_MAX)];
.........................................
};
/**
* input_set_capability - mark device as capable of a certain event
* @dev: device that is capable of emitting or accepting event
* @type: type of the event (EV_KEY, EV_REL, etc...)
* @code: event code
*
* In addition to setting up corresponding bit in appropriate capability
* bitmap the function also adjusts dev->evbit.
*/
/* 记录本设备对于哪些事件感兴趣(对其进行处理)*/
void input_set_capability(struct input_dev *dev, unsigned int type, unsigned int code)
{
switch (type) {
case EV_KEY:
__set_bit(code, dev->keybit);//比如按键,应该对哪些键值的按键进行处理(对于其它按键不予理睬)
break;
case EV_REL:
__set_bit(code, dev->relbit);
break;
case EV_ABS:
__set_bit(code, dev->absbit);
break;
case EV_MSC:
__set_bit(code, dev->mscbit);
break;
case EV_SW:
__set_bit(code, dev->swbit);
break;
case EV_LED:
__set_bit(code, dev->ledbit);
break;
case EV_SND:
__set_bit(code, dev->sndbit);
剩余11页未读,继续阅读
yaxinsn
- 粉丝: 62
- 资源: 30
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0