现在的位置: 首页 > 综合 > 正文

Linux输入子系统分析(六)

2013年02月20日 ⁄ 综合 ⁄ 共 1845字 ⁄ 字号 评论关闭
输入子系统核心 input core

     通过前面的学习,我们学习了输入子系统中的输入设备驱动和输入事件驱动,这两者都是基于输入核心层input core 基础之上的。input core负责管理所有资源并连接输入设备驱动和输入事件驱动。这小节就让我们来深入input core,探其究竟...


1、input core 初始化

     输入核心层input core 在drivers/input/input.c文件中实现,下面来研究其源代码。


static int __init input_init(void)
{
int err;
/*
* 注册一个input_class类
*/
err = class_register(&input_class);
if (err) {
pr_err("unable to register input_dev class\n");
return err;
}
/*
     * 在/proc/bus/input下面创建两个节点devices和handlers,
     * 通过打印这两个节点的内容可以查看输入子系统的设备驱
     * 动层信息和处理层信息。
*/
err = input_proc_init();
if (err)
goto fail1;
/*
*申请注册输入子系统的主设备号13,并注册文件结构体input_fops。
*input core申请了主设备号,那么所有打开输入设备的处理请求都
*会传给input_fops的打开函数处理input_open_file
*
*/
err = register_chrdev(INPUT_MAJOR, "input", &input_fops);
if (err) {
pr_err("unable to register char major %d", INPUT_MAJOR);
goto fail2;
}
return 0;

      fail2: input_proc_exit();
      fail1: class_unregister(&input_class);
       return err;
}

2、应用程序访问输入设备
上面我们知道了,当应用程序访问输入设备文件的时候,当调用open打开输入设备文件时,导致输入核心层的input_open_file的调用。以下是input_open_file的源码:

static int input_open_file(struct inode *inode, struct file *file)
{
struct input_handler *handler;
const struct file_operations *old_fops, *new_fops = NULL;
int err;

err = mutex_lock_interruptible(&input_mutex);
if (err)
return err;

/* No load-on-demand here? 
*  根据次设备号从input_table取出用户需要的handler

        *  把取到的handler支持的文件操作拷贝到new_fops中
*/
handler = input_table[iminor(inode) >> 5];
if (handler)
new_fops = fops_get(handler->fops);

mutex_unlock(&input_mutex);

/*
 * That's _really_ odd. Usually NULL ->open means "nothing special",
 * not "no device". Oh, well...
 */
if (!new_fops || !new_fops->open) {
fops_put(new_fops);
err = -ENODEV;
goto out;
}

old_fops = file->f_op;
file->f_op = new_fops;
        /*

         * file指的是用户想要打开的输入设备文件
         * new_fops->open(inode, file)是调用对应handler的XX_open函数
         * 到这里,input core已经完成了输入设备驱动和输入事件驱动的通信管道
         * 剩下的就是输入设备驱动报告事件,输入事件驱动处理事件并与应用程序
         * 交互数据信息
*/
err = new_fops->open(inode, file);
if (err) {
fops_put(file->f_op);
file->f_op = fops_get(old_fops);
}
fops_put(old_fops);
out:
return err;
}

3、



抱歉!评论已关闭.