ImageVerifierCode 换一换
格式:DOCX , 页数:41 ,大小:69.46KB ,
资源ID:16421475      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/16421475.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(linux kernel input 子系统分析Word格式.docx)为本站会员(b****4)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

linux kernel input 子系统分析Word格式.docx

1、 25 26 27 irqreturn_t do_irq(int irqno , void *data) 28 29 /事件上报 30 /算出第几个按键 31 int keynum = irqno - IRQ_EINT(26) ; /0 - 3 32 unsigned int val ; 33 34 val = ioread32(gpxconf + 1); 35 val = val 2 ; 36 37 /printk(keynum:%d val:%#x n , keynum , val); 38 switch(keynum) 39 /事件上报函数. 40 case 0: input_repor

2、t_key(device,KEY_A, !(val & (1 keynum) ); break; 41 case 1: input_report_key(device,KEY_B, ! 42 case 2: input_report_key(device,KEY_C, ! 43 case 3: input_report_key(device,KEY_D, ! 44 45 46 /同步 47 input_sync(device); 48 49 return IRQ_HANDLED ; 50 51 52 53 /* 54 /模块入口出口 55 56 static int _init test_in

3、it(void) 57 58 int ret ; 59 int i ; 60 61 for(i = 0 ; i ARRAY_SIZE(irqs) ; i+) 62 /请求中断 63 ret = request_irq(irqsi , do_irq , IRQF_TRIGGER_FALLING| IRQF_TRIGGER_RISING | IRQF_SHARED , myirq,(void *)88); 64 if(ret 0) 65 goto Err ; 66 67 68 /分配一个事件上报设备结构体 69 device = input_allocate_device(); 70 if(IS_

4、ERR(device) 71 72 ret = PTR_ERR(device); 73 goto Err1 ; 74 75 76 /#define BITS_PER_LONG 32 77 /#define BIT_MASK(nr) (1UL evbitBIT_WORD(EV_KEY) |= BIT_MASK(EV_KEY); /使能按键事件类型 81 device-keybitBIT_WORD(KEY_A) |= BIT_MASK(KEY_A) ; /使能按键值为A的事件 82 device-keybitBIT_WORD(KEY_B) |= BIT_MASK(KEY_B) ; 83 devic

5、e-keybitBIT_WORD(KEY_C) |= BIT_MASK(KEY_C) ; 84 device-keybitBIT_WORD(KEY_D) |= BIT_MASK(KEY_D) ; 85 86 87 /注册一个input设备 上报类型 上报键值 88 ret = input_register_device(device); 89 if(ret 2 device-3 device-4 device-5 device- /使能按键值为A的事件这个结构体的原型是这样的: 1 struct input_dev 2 const char *name; /设备名字 3 const char

6、*phys; /设备在系统中的物理路径 4 const char *uniq; /设备的唯一标识码 5 struct input_id id; /设备id,包含总线id ,厂商id , 与input_handler匹配的时会用到 7 unsigned long propbitBITS_TO_LONGS(INPUT_PROP_CNT); /设备性质 8 9 unsigned long evbitBITS_TO_LONGS(EV_CNT);/设备支持的事件类型 10 unsigned long keybitBITS_TO_LONGS(KEY_CNT);/支持的具体的按键。按钮事件 11 unsig

7、ned long relbitBITS_TO_LONGS(REL_CNT);/支持的具体的相对坐标事件 12 unsigned long absbitBITS_TO_LONGS(ABS_CNT);/支持的具体的绝对坐标事件 13 unsigned long mscbitBITS_TO_LONGS(MSC_CNT);/支持的具体的混杂事件 14 unsigned long ledbitBITS_TO_LONGS(LED_CNT);/支持的具体的led指示灯事件 15 unsigned long sndbitBITS_TO_LONGS(SND_CNT);/支持的具体的音效事件 unsigned l

8、ong ffbitBITS_TO_LONGS(FF_CNT);/支持的具体的力反馈事件 16 unsigned long swbitBITS_TO_LONGS(SW_CNT);/支持的具体的开关事件 17 18 unsigned int hint_events_per_packet;19 20 unsigned int keycodemax; / 键盘码表的大小 21 unsigned int keycodesize; /键盘码中的元素个数 22 void *keycode; /设备的键盘码表 23 /* 两个可选方法 , 用于配置和获取键盘码表 */ 24 int (*setkeycode)

9、(struct input_dev *dev, 25 const struct input_keymap_entry *ke, 26 unsigned int *old_keycode);27 int (*getkeycode)(struct input_dev *dev, 28 struct input_keymap_entry *ke);29 30 struct ff_device *ff; /* 如果设备支持力反馈,则该成员将指向力反馈的设备描述31 结构 */32 33 unsigned int repeat_key; /*保存上一个键值,实现软件自动重复按键 */ 34 struct

10、 timer_list timer; /*用于软件自动重复按键的定时器 */ 35 36 int repREP_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 keyBITS_TO_LONGS(KEY_CNT);/反映设备按键按钮的当前状态 46 unsigned long ledBITS_TO_LONGS(LED_CNT);/反映设备led灯的当前状态 47 unsigned lon

11、g sndBITS_TO_LONGS(SND_CNT);/反映设备音效的当前状态 48 unsigned long swBITS_TO_LONGS(SW_CNT);/反映设备开关的当前状态 49 50 /* 提供以下4个设备驱动层的操作接口,根据具体的设备需求实现他们 */ 51 int (*open)(struct input_dev *dev); /将在input_open_device()中调用 52 void (*close)(struct input_dev *dev);/将在input_close_device()中调用 53 int (*flush)(struct input_d

12、ev *dev, struct file *file);55 /*(event)用于处理送到设备驱动层来的事件,很多事件在事件处理层被处理,但有很多事件仍需56 要送到设备驱动中,如led指示灯事件和音效事件,因为这些操作通常需要设备驱动执行*/57 int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);58 59 struct input_handle _rcu *grab;60 61 spinlock_t event_lock;62 struct mutex mutex;63

13、 64 /* 记录输入事件处理程序(input handlers)调用设备open()方法的次数,保证设备open()是在第一个调用input_open_device()中被调用, 设备close()方法是在最后一次调用input_close_device()中被调用 */65 unsigned int users;66 bool going_away;67 68 bool sync; /上次同步事件(EV_SYNC)发生后没有新事件产生,则被设置为1*/ 69 70 struct device dev; /内嵌设备device结构 71 struct list_head h_list; /与

14、该设备相关的输入句柄(input handles)列表 72 struct list_head node;/通过该成员,系统中的所有的input_dev对象被管理 73 ;上面是我做的一些注释 .而且在上面的按键设备的驱动中 , 我还对evbit , 和keybit 两个数值进行赋值.它那个宏定义是这样的:1 /#define BITS_PER_LONG 32 2 /#define BIT_MASK(nr) (1UL 3 /#define BIT_WORD(nr) (nr) / BITS_PER_LONG)这里边所支持的事件类型和支持的具体的按键按钮类型是这样的: 1 #define EV_S

15、YN 0x00 2 #define EV_KEY 0x01 3 #define EV_REL 0x02 4 #define EV_ABS 0x03 5 #define EV_MSC 0x04 6 #define EV_SW 0x05 7 #define EV_LED 0x11 8 #define EV_SND 0x12 9 #define EV_REP 0x14 9 #define EV_FF 0x15 10 #define EV_PWR 0x16 11 #define EV_FF_STATUS 0x17 12 #define EV_MAX 0x1f 12 #define EV_CNT (EV

16、_MAX+1) 所支持的按键按钮类型就比较多了 1 2 #define KEY_RESERVED 0 3 #define KEY_ESC 1 4 #define KEY_1 2 5 #define KEY_2 3 6 #define KEY_3 4 7 #define KEY_4 5 8 #define KEY_5 6 9 #define KEY_6 7 10 #define KEY_7 8 11 #define KEY_8 9 12 #define KEY_9 10 13 #define KEY_0 11 14 .这些相对应的类型都是用一些宏定义来定义 , 到上报个核心层再上报到事件处理层的

17、时候以一个结构体的形式的数据体现给用户, 后面会讲到这个结构体回到源代码:然后就是注册一个 input 设备 把刚才赋值的事件上报类型传进去:1 /注册一个input设备 上报类型 上报键值 2 ret = input_register_device(device);3 if(ret 10 11 /printk(12 switch(keynum) 13 14 case 0:15 case 1:16 case 2:17 case 3:18 20 /同步 21 input_sync(device);22 23 return IRQ_HANDLED ;24 25 其实总的来说我们做了两个事情 , 第

18、一个就是触发中断后 ,我们上报了是第几个按键触发的中断 , 并进行同步处理.现在 , 我已经把这个最简单的一个按键事件上报驱动讲解了一遍 , 其实我们有很多疑问 :第一个就是: 我们怎么分配的一个事件上报结构体第二个问题 , 我们是怎么将事件层层上报 , 将input driver , input core , input handler 这三层联系起来的 .第三个问题 , 我们给上层提供的是一个怎么样的借口 , 给上层上报的是一个怎么的数据.其实第一个问题比较简单 , 我只是为了拿出来缓解一下当前比较紧张的气氛 , 透露一下 , 第二个问题才是关键!第一个问题它只是做了一个分配空间并对其初始

19、化值的操作: 1 */申请一个新的input device 2 struct input_dev *input_allocate_device(void) 3 4 struct input_dev *dev; 6 dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL); 7 if (dev) 8 dev-dev.type = &input_dev_type; 9 dev-dev.class = &input_class;10 device_initialize(&dev-dev);11 mutex_init(&mutex);12 spin_loc

20、k_init(&event_lock);13 INIT_LIST_HEAD(&h_list);14 INIT_LIST_HEAD(&node);15 16 _module_get(THIS_MODULE);17 18 19 return dev;20 21 EXPORT_SYMBOL(input_allocate_device);是不是觉得自己竟然能两眼就能看懂这些代码 , 别惊讶 , 其实你自己挺强的 , 就连我都要花喵一眼的时间去看才能看懂它下面才是重头戏: input core 代码.在前面的驱动当中 , 我们在分配完input_dev 结构体后 , 我们直接在没有产生并触发按键中断之前 , 抢先注册了一个input 设备其实如果按照标准的写法 , 我们注册一个input

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1