Linux input子系统实例分析(二)
紧接着上一节的实例我们来分析调用的input子系统的接口:
1. input_dev,用来标识输入设备
1: struct input_dev {
2: const char *name; //设备名
3: const char *phys; // 设备在系统中路径
4: const char *uniq;
5: struct input_id id; //与input_handler匹配用的id
6:
7: unsigned long propbit[BITS_TO_LONGS(INPUT_PROP_CNT)];
8:
9: unsigned long evbit[BITS_TO_LONGS(EV_CNT)]; //设备所支持事件类型,主要有EV_SYNC,EV_KEY,EV_REL,EV_ABS等
10: unsigned long keybit[BITS_TO_LONGS(KEY_CNT)];// 按键所对应的位图
11: unsigned long relbit[BITS_TO_LONGS(REL_CNT)];// 相对坐标对应位图
12: unsigned long absbit[BITS_TO_LONGS(ABS_CNT)];// 绝对坐标对应位图
13: unsigned long mscbit[BITS_TO_LONGS(MSC_CNT)];//支持其它事件
14: unsigned long ledbit[BITS_TO_LONGS(LED_CNT)];//支持led事件
15: unsigned long sndbit[BITS_TO_LONGS(SND_CNT)];//支持声音事件
16: unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];//支持受力事件
17: unsigned long swbit[BITS_TO_LONGS(SW_CNT)];//支持开关机事件
18:
19: unsigned int hint_events_per_packet;
20:
21: unsigned int keycodemax;
22: unsigned int keycodesize;
23: void *keycode;
24:
25: int (*setkeycode)(struct input_dev *dev,
26: const struct input_keymap_entry *ke,
27: unsigned int *old_keycode);
28: int (*getkeycode)(struct input_dev *dev,
29: struct input_keymap_entry *ke);
30:
31: struct ff_device *ff;
32:
33: unsigned int repeat_key;//最近一次的按键值
34: struct timer_list timer;
35:
36: int rep[REP_CNT];
37:
38: struct input_mt_slot *mt;
39: int mtsize;
40: int slot;
41: int trkid;
42:
43: struct input_absinfo *absinfo;
44:
45: unsigned long key[BITS_TO_LONGS(KEY_CNT)];//反应设备当前的按键状态
46: unsigned long led[BITS_TO_LONGS(LED_CNT)];//反应设备当前的led状态
47: unsigned long snd[BITS_TO_LONGS(SND_CNT)];//反应设备当前的声音输入状态
48: unsigned long sw[BITS_TO_LONGS(SW_CNT)];//反应设备当前的开关状态
49:
50: int (*open)(struct input_dev *dev);//第一次打开设备时调用,初始化设备用
51: void (*close)(struct input_dev *dev);//最后一个应用程序释放设备时用,关闭设备
52: int (*flush)(struct input_dev *dev, struct file *file);/*用于处理传递给设备的事件,如LED事件和声音事件*/
53: // 事件处理函数,主要是接收用户下发的命令,如点亮led;
54: int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);
55:
56: struct input_handle __rcu *grab; //当前占有该设备的input_handle
57:
58: spinlock_t event_lock;
59: struct mutex mutex;
60:
61: unsigned int users; //打开该设备的用户数量(input handlers)
62: bool going_away;
63:
64: bool sync;
65:
66: struct device dev;
67:
68: struct list_head h_list; // 设备所支持的input handle;
69: struct list_head node; //用于将此input_dev链接到input_dev_list
70: };
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
2.把输入设备注册进核心层 int input_register_device(struct input_dev *dev)
1: int input_register_device(struct input_dev *dev)
2: {
3: static atomic_t input_no = ATOMIC_INIT(0);
4: struct input_handler *handler;
5: const char *path;
6: int error;
7:
8: /* Every input device generates EV_SYN/SYN_REPORT events. */
9: __set_bit(EV_SYN, dev->evbit);// /*表示设备支持所有的事件*/
10:
11: /* KEY_RESERVED is not supposed to be transmitted to userspace. */
12: __clear_bit(KEY_RESERVED, dev->keybit);
13:
14: /* Make sure that bitmasks not mentioned in dev->evbit are clean. */
15: input_cleanse_bitmasks(dev);
16:
17: if (!dev->hint_events_per_packet)
18: dev->hint_events_per_packet =
19: input_estimate_events_per_packet(dev);
20:
21: /*
22: * If delay and period are pre-set by the driver, then autorepeating
23: * is handled by the driver itself and we don't do it in input.c.
24: */
25: init_timer(&dev->timer);//初始化定时器
26: /*如果dev->rep[REP_DELAY]和dev->rep[REP_PERIOD]没有设值,
27: 则将其赋默认值,这主要是为自动处理重复按键定义*/
28: if (!dev->rep[REP_DELAY] && !dev->rep[REP_PERIOD]) {
29: dev->timer.data = (long) dev;
30: dev->timer.function = input_repeat_key;//定时器处理函数
31: dev->rep[REP_DELAY] = 250;
32: dev->rep[REP_PERIOD] = 33;
33: }
34:
35: if (!dev->getkeycode)//获取键值
36: dev->getkeycode = input_default_getkeycode;
37:
38: if (!dev->setkeycode)//设置键值
39: dev->setkeycode = input_default_setkeycode;
40: //设置input_dev中的device的名字
41: dev_set_name(&dev->dev, "input%ld",
42: (unsigned long) atomic_inc_return(&input_no) - 1);
43:
44: error = device_add(&dev->dev);//将input_dev包含的device结构注册到Linux设备模型中,并可以在sysfs文件系统中表现出来。
45: if (error)
46: return error;
47:
48: path = kobject_get_path(&dev->dev.kobj, GFP_KERNEL);
49: pr_info("%s as %s\n",
50: dev->name ? dev->name : "Unspecified device",
51: path ? path : "N/A");
52: kfree(path);
53:
54: error = mutex_lock_interruptible(&input_mutex);
55: if (error) {
56: device_del(&dev->dev);
57: return error;
58: }
59:
60: list_add_tail(&dev->node, &input_dev_list);//添加到input device 链表
61:
62: list_for_each_entry(handler, &input_handler_list, node)//
63: input_attach_handler(dev, handler);
64:
65: input_wakeup_procfs_readers();
66:
67: mutex_unlock(&input_mutex);
68:
69: return 0;
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
3.调用input_report_key函数报告此事件
1: static inline void input_report_key(struct input_dev *dev, unsigned int code, int value)
2: {
3: input_event(dev, EV_KEY, code, !!value);
4: }
input_report_key函数参数,1.input_dev设备,2。按键值 3.按键的状态(1按下,0松开)
在input.h中定义了按键类code的值,BTN_0,BTN_1,KEY_A KEY_B等等这样的键值
此函数只是调用了input_event函数,这个函数是总的事件报告函数,
1: void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
2: {
3: unsigned long flags;
4:
5: if (is_event_supported(type, dev->evbit, EV_MAX)) { //(1)
6:
7: spin_lock_irqsave(&dev->event_lock, flags); //(2)
8: add_input_randomness(type, code, value); //(3)
9: input_handle_event(dev, type, code, value); //(4)
10: spin_unlock_irqrestore(&dev->event_lock, flags);//(5)
11: }
12: }
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
参数1.input_dev 2.事件类型(如EV_KEY键盘事件) 3.此类型具体事件code(如KEY_A,键A) 4.此事件的值(如1,按键按下)
(1)设备是否支持该事件类型。下面分析
(2)自旋锁上锁
(3)因为按键是随机事件,所以对随机熵有贡献,对于驱动无关。具体不懂
(4)进一步处理报告的事件
(5)自旋锁解锁
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
Linux input子系统实例分析(二)的更多相关文章
- Linux input子系统实例分析(一)
这是一个简单的输入设备驱动实例.这个输入设备只有一个按键,按键被连接到一条中断线上,当按键被按下时,将产生一个中断,内核将检测到这个中断,并对其进行处理.该实例的代码如下: 1: #inclu ...
- Linux Input子系统浅析(二)-- 模拟tp上报键值【转】
转自:https://blog.csdn.net/xiaopangzi313/article/details/52383226 版权声明:本文为博主原创文章,未经博主允许不得转载. https://b ...
- Linux input子系统分析
输入输出是用户和产品交互的手段,因此输入驱动开发在Linux驱动开发中很常见.同时,input子系统的分层架构思想在Linux驱动设计中极具代表性和先进性,因此对Linux input子系统进行深入分 ...
- Linux Input子系统
先贴代码: //input.c int input_register_handler(struct input_handler *handler) { //此处省略很多代码 list_for_each ...
- 一些有用的javascript实例分析(二)
原文:一些有用的javascript实例分析(二) 5 求出数组中所有数字的和 window.onload = function () { var oBtn = document.getElement ...
- Linux内核启动代码分析二之开发板相关驱动程序加载分析
Linux内核启动代码分析二之开发板相关驱动程序加载分析 1 从linux开始启动的函数start_kernel开始分析,该函数位于linux-2.6.22/init/main.c start_ke ...
- Linux input子系统 io控制字段【转】
转自:http://www.cnblogs.com/leaven/archive/2011/02/12/1952793.html http://blog.csdn.net/guoshaobei/arc ...
- Linux时间子系统之(二):软件架构
专题文档汇总目录 Notes:从框架上讲解了时间子系统,从底向上包括CPU Local TImer.Global Counter.Clock Souce/Clock Events模块管理.Tick D ...
- Linux input子系统编程、分析与模板
输入设备都有共性:中断驱动+字符IO,基于分层的思想,Linux内核将这些设备的公有的部分提取出来,基于cdev提供接口,设计了输入子系统,所有使用输入子系统构建的设备都使用主设备号13,同时输入子系 ...
随机推荐
- performSelectorOnMainThread
在多线程操作中,有一个著名的错误,叫做"Tried to obtain the web lock from a thread other than the main thread or th ...
- 【编程工具】如何用Sublime Text3建立本地服务器和站点
不久前,我学习了使用DW(DreamWare CS6)这款软件来学习HTML和制作静态网页,但是总觉得这款图形化软件不太适合我这种喜欢写代码的码农,所以最终我使用的是Sublime Text3这款软件 ...
- 【LeetCode】Integer to Roman(整数转罗马数字)
这道题是LeetCode里的第12道题. 吐了,刚做完"罗马数字转整数",现在又做这个.这个没什么想法,只能想到使用if语句嵌套,或者使用哈希表.但哈希表我还不熟练啊.先拿if嵌套 ...
- 【JavaScript 6—基础知识点】:正则表达式(应用)
导读:其实,我不像大家一样,从一开始就重视着正则表达式,我甚至都觉得好浪费时间浪费精力,都没用的.因为,如果我要判断是不是为数字,我可以使用Numberic()方法,如果要去空格的话,使用trim() ...
- 最短路POJ 1062 昂贵的聘礼
C - 昂贵的聘礼 Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Submit St ...
- iOS学习笔记19-地图(一)定位CoreLocation
一.定位介绍 现在很多社交.电商.团购应用都引入了地图和定位功能,似乎地图功能不再是地图应用和导航应用所特有的.的确,有了地图和定位功能确实让我们的生活更加丰富多彩,极大的改变了我们的生活方式.要实现 ...
- 使用Apriori算法进行关联分析
关联分析是一种在大规模数据集中寻找有趣关系的任务.这些关系可以有两种形式:频繁项集或者关联规则.频繁项集是指经常出现在一块的物品的集合,关联规则暗示两种物品之间可能存在很强的关系.一个项集的支持度被定 ...
- BZOJ 2440 [中山市选2011]完全平方数 ——莫比乌斯函数
$\sum_{i=1}^n[i==d^2*p]$ 其中p无平方因子$=\sum_{d^2\mid n,d>=2}\sum_{i=1}^{\lfloor {n/d^2} \rfloor} \lef ...
- [POJ2778]DNA Sequence(AC自动机 + DP + 矩阵优化)
传送门 AC自动机加DP就不说了 注意到 m <= 10,所以模式串很少. 而 n 很大就需要 log 的算法,很容易想到矩阵. 但是该怎么构建? 还是矩阵 A(i,j) = ∑A(i,k) * ...
- 刷题总结——书架(bzoj1861)
题解: Description 小T有一个很大的书柜.这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列.她用1到n的正整数给每本书都编了号. 小T在看书的时候,每次取出一本书,看完后放回书柜然 ...