内核:一个中断如何对应多个句柄

来源:互联网 发布:ipad软件连不上网络 编辑:程序博客网 时间:2024/05/22 20:14

input子系统


input子系统代码位置:kernel/drivers/input/input.c

这个文件完成input系统最原始的初始化,subsys_initcall开始子系统的初始化,并封装EXPORT_SYMBOL给其他驱动调用的接口


在input_init中,三件事:

err = class_register(&input_class);if (err) {pr_err("unable to register input_dev class\n");return err;}err = input_proc_init();if (err)goto fail1;err = register_chrdev(INPUT_MAJOR, "input", &input_fops);if (err) {pr_err("unable to register char major %d", INPUT_MAJOR);goto fail2;}

创建一个class,proc目录下节点,和注册input的方法集

对开发很有用的是proc的节点,我们看下代码,才能更好地利用它

static int __init input_proc_init(void){struct proc_dir_entry *entry;proc_bus_input_dir = proc_mkdir("bus/input", NULL);if (!proc_bus_input_dir)return -ENOMEM;entry = proc_create("devices", 0, proc_bus_input_dir,    &input_devices_fileops);if (!entry)goto fail1;entry = proc_create("handlers", 0, proc_bus_input_dir,    &input_handlers_fileops);if (!entry)goto fail2;return 0; fail2:remove_proc_entry("devices", proc_bus_input_dir); fail1: remove_proc_entry("bus/input", NULL);return -ENOMEM;}

分如下步骤:

1. "bus/input"目录创建

2. 在"bus/input"目录下创建proc目录devices,它的方法集有

static const struct file_operations input_devices_fileops = {.owner= THIS_MODULE,.open= input_proc_devices_open,.poll= input_proc_devices_poll,.read= seq_read,.llseek= seq_lseek,.release= seq_release,};

这里要高度重视这些方法集,因为方法集才是创建这些节点的目的,内核很多的调用都是通过方法集调用,所以即使用sourceinsight也很难直接找到注册位置和调用位置

static const struct seq_operations input_devices_seq_ops = {.start= input_devices_seq_start,.next= input_devices_seq_next,.stop= input_seq_stop,.show= input_devices_seq_show,};static int input_proc_devices_open(struct inode *inode, struct file *file){return seq_open(file, &input_devices_seq_ops);}

open方法就完成一件事:open这个节点的文件,这个节点又对应着一系列的调用,分别有start next stop show;看方法的名字也能知道,这些方法的调用是先start,再next,最后stop,可以通过show,用cat查看一些信息。明白这些,就可以理解,这些方法里面,是一些句柄的链表,每次调用device的open,都会把devices的所有句柄,按照start-next-next-...-stop的方式,这就实现了一个open,能够有多个功能。

“handlers”节点和“devieces”节点注册方式类似,里面关联的是很多的中断句柄

static const struct seq_operations input_handlers_seq_ops = {.start= input_handlers_seq_start,.next= input_handlers_seq_next,.stop= input_seq_stop,.show= input_handlers_seq_show,};static int input_proc_handlers_open(struct inode *inode, struct file *file){return seq_open(file, &input_handlers_seq_ops);}static const struct file_operations input_handlers_fileops = {.owner= THIS_MODULE,.open= input_proc_handlers_open,.read= seq_read,.llseek= seq_lseek,.release= seq_release,};

我们实际用下这些节点

shell@android:/proc/bus/input # lsdeviceshandlersshell@android:/proc/bus/input # 

shell@android:/proc/bus/input # cat devices                                    I: Bus=0000 Vendor=0001 Product=0001 Version=0100N: Name="headsetdet"P: Phys=S: Sysfs=/devices/platform/headsetdet.0/input/input0U: Uniq=H: Handlers=event0 B: PROP=0B: EV=3B: KEY=1I: Bus=0019 Vendor=0001 Product=0001 Version=0100N: Name="keypad"P: Phys=gpio-keys/input0S: Sysfs=/devices/platform/keypad/input/input1U: Uniq=H: Handlers=kbd event1 keychord B: PROP=0B: EV=3B: KEY=8000 100000 0 0 0I: Bus=0000 Vendor=0000 Product=0000 Version=0000N: Name="ft5x0x_ts"P: Phys=S: Sysfs=/devices/virtual/input/input2U: Uniq=H: Handlers=cpufreq_interactive event2 B: PROP=2B: EV=9B: ABS=2658000 0I: Bus=0000 Vendor=0000 Product=0000 Version=0000N: Name="lightsensor-level"P: Phys=S: Sysfs=/devices/virtual/input/input3U: Uniq=H: Handlers=event3 B: PROP=0B: EV=9B: ABS=100 10000000shell@android:/proc/bus/input # 

shell@android:/proc/bus/input # cat handlers                                   N: Number=0 Name=kbdN: Number=1 Name=cpufreq_interactiveN: Number=2 Name=sysrq (filter)N: Number=3 Name=evdev Minor=64N: Number=4 Name=keychordshell@android:/proc/bus/input # 

cpufreq_interactive就是interactive策略,增加对input及时响应的一个句柄。
























原创粉丝点击