




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)
文檔簡介
1、input子系統(tǒng)分析Jason一、概述在linux下,按鍵、觸摸屏、鼠標(biāo)等都可以利用input接口函數(shù)來實現(xiàn)設(shè)備驅(qū)動。1,linux輸入子系統(tǒng)主要分三層: 驅(qū)動,輸入CORE, 事件處理層。驅(qū)動根據(jù)CORE提供的接口,向上報告發(fā)生的按鍵動作。然后CORE根據(jù)驅(qū)動的類型,分派這個報告給對應(yīng)的事件處理層進行處事。事件處理層把數(shù)據(jù)變化反應(yīng)到設(shè)備模型的文件中(事件緩沖區(qū))。并通知在這些設(shè)備模型文件上等待的進程。2,輸入子系統(tǒng)在KERNEL初始化時被初始化。會創(chuàng)建所有類型輸入輸出設(shè)備的邏輯設(shè)備(及sysfs結(jié)點)。當(dāng)硬件注冊時,就會調(diào)用所有類型的input handler的connect函數(shù),根據(jù)硬件注
2、冊的結(jié)構(gòu)來判斷是否與自己相關(guān),然后再創(chuàng)建一個具體的設(shè)備結(jié)點。3,驅(qū)動只負(fù)責(zé)的把輸入設(shè)備注冊到輸入子系統(tǒng)中,然后輸入子系統(tǒng)來創(chuàng)建對應(yīng)的具體設(shè)備結(jié)點。而事件處理層,在初始化時,需要注冊所一類設(shè)備的輸入事件處理函數(shù)及相關(guān)接口4,一類input handler可以和多個硬件設(shè)備相關(guān)聯(lián),創(chuàng)建多個設(shè)備節(jié)點。而一個設(shè)備也可能與多個input handler相關(guān)聯(lián),創(chuàng)建多個設(shè)備節(jié)點。二、輸入設(shè)備結(jié)構(gòu)體1.input_dev 這是input設(shè)備基本的設(shè)備結(jié)構(gòu),每個input驅(qū)動程序中都必須分配初始化這樣一個結(jié)構(gòu),成員比較多 代碼路徑 kernel/include/linux/input.h1. str
3、uct input_dev 2. const char *name; /設(shè)備名 3. const char *phys; /設(shè)備系統(tǒng)層的物理路徑 4. const&
4、#160;char *uniq; / 5. struct input_id id; /輸入設(shè)備id 總線類型;廠商編號,產(chǎn)品id,產(chǎn)品版本 6. 7. unsigned long evbitBITS_TO_LONGS(EV_CNT); /事件類型標(biāo)志位
5、;8. unsigned long keybitBITS_TO_LONGS(KEY_CNT); /鍵盤事件標(biāo)志位 9. unsigned long relbitBITS_TO_LONGS(REL_CNT); /相對位移事件標(biāo)志位 10. unsigned long absbitBIT
6、S_TO_LONGS(ABS_CNT); /絕對位移事件標(biāo)志位 11. unsigned long mscbitBITS_TO_LONGS(MSC_CNT); /雜項事件標(biāo)志位 12. unsigned long ledbitBITS_TO_LONGS(LED_CNT); /led指示燈標(biāo)志位
7、13. unsigned long sndbitBITS_TO_LONGS(SND_CNT); /聲音事件 14. unsigned long ffbitBITS_TO_LONGS(FF_CNT); /強制反饋事件 15. unsigned long swbitBITS_TO_LONGS(SW_CNT);&
8、#160;/開關(guān)事件標(biāo)志位 16. 17. unsigned int hint_events_per_packet; 18. unsigned int keycodemax; /鍵盤碼表大小 19. unsigned in
9、t keycodesize; /鍵盤碼大小 20. void *keycode; /鍵盤碼表指針 21. 22. int (*setkeycode)(struct input_dev *
10、dev,unsigned int scancode, unsigned int keycode); /設(shè)置鍵盤碼 23. int (*getkeycode)(struct input_dev *dev,unsigned int scancode, unsigned int *keycode); /獲取鍵盤碼 24.
11、160; int (*setkeycode_new)(struct input_dev *dev,const struct input_keymap_entry *ke,unsigned int *old_keycode); 25. int (*getkeycode_new)(struct input_dev *dev,struct input_keymap_e
12、ntry *ke); 26. 27. struct ff_device *ff; /強制反饋設(shè)備 28. unsigned int repeat_key; /重復(fù)按鍵標(biāo)志位 29. struct timer_list
13、;timer; /定時器 30. int repREP_CNT; /重復(fù)次數(shù) 31. struct input_mt_slot *mt; 32. int mtsize; 33.
14、; int slot; 34. struct input_absinfo *absinfo; 35. unsigned long keyBITS_TO_LONGS(KEY_CNT); / 36. unsigned long ledBITS_TO_LONGS(LED_CNT);
15、 / 37. unsigned long sndBITS_TO_LONGS(SND_CNT); / 38. unsigned long swBITS_TO_LONGS(SW_CNT); / 39. 40. int (*open
16、)(struct input_dev *dev); /open方法 41. void (*close)(struct input_dev *dev); /close方法 42. int (*flush)(struct input_dev *dev, struct fi
17、le *file); 43. int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value); 44. 45. struct input_handle _rcu *grab;
18、60; 46. spinlock_t event_lock; 47. struct mutex mutex; 48. unsigned int users; 49. bool going_away; 50.
19、60;bool sync; 51. struct device dev; /設(shè)備文件 52. struct list_head h_list; /input_handler處理器鏈表頭 53. struct lis
20、t_head node; /input_device設(shè)備鏈表頭 54. ; 三、input_handler 輸入處理器這是事件處理器的數(shù)據(jù)結(jié)構(gòu),代表一個事件處理器代碼路徑 kernel/include/linux/input.h1. struct input_handler 2. void *private; /私有數(shù)據(jù) 3.
21、 void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value); /事件處理 4. bool (*filter)(struct input_handle *handle,
22、60;unsigned int type, unsigned int code, int value); /過濾器 5. bool (*match)(struct input_handler *handler, struct input_dev *dev); /設(shè)備匹配 6.
23、0; int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id); /設(shè)備連接 7. void (*disconnect)(struct input_handle *handle);
24、160;/設(shè)備斷開連接 8. void (*start)(struct input_handle *handle); 9. const struct file_operations *fops; /輸入操作函數(shù)集 10. int minor; /次設(shè)備號 11. &
25、#160; const char *name; /設(shè)備名 12. const struct input_device_id *id_table; /輸入設(shè)備 id表 13. struct list_head h_list; /input_handler處理
26、器鏈表頭 14. struct list_head node; /input_device設(shè)備鏈表頭 15. ; 四、input_handle input_handle 結(jié)構(gòu)體代表一個成功配對的input_dev和input_handler代碼路徑 kernel/include/linux/input.hstruct input_handle 1.
27、 void *private; /每個配對的事件處理器都會分配一個對應(yīng)的設(shè)備結(jié)構(gòu),如evdev事件處理器的evdev結(jié)構(gòu),注意這個結(jié)構(gòu)與設(shè)備驅(qū)動層的input_dev不同,初始化handle時,保存到這里。 2. int open; /打開標(biāo)志,每個input_handle 打開后才能操作,這個一般通過事件處理器的open方法間接設(shè)置 3. const char *name;
28、4. struct input_dev *dev; /關(guān)聯(lián)的input_dev結(jié)構(gòu) 5. struct input_handler *handler; /關(guān)聯(lián)的input_handler結(jié)構(gòu) 6. struct list_head d_node; /input_handle通過d_node連接到了input_dev上的h_list鏈表上 7.
29、60; struct list_head h_node; /input_handle通過h_node連接到了input_handler的h_list鏈表上 8. ; 五、三個數(shù)據(jù)結(jié)構(gòu)之間的關(guān)系input_dev 是硬件驅(qū)動層,代表一個input設(shè)備input_handler 是事件處理層,代表一個事件處理器input_handle 個人認(rèn)為屬于核心層,代表一個配對的input設(shè)備與input事件處理器input_dev 通過全局的input_dev_list鏈接在一起。設(shè)備注冊的時候?qū)崿F(xiàn)這個操作。input_handler 通過全局的input_hand
30、ler_list鏈接在一起。事件處理器注冊的時候?qū)崿F(xiàn)這個操作(事件處理器一般內(nèi)核自帶,一般不需要我們來寫)input_hande 沒有一個全局的鏈表,它注冊的時候?qū)⒆约悍謩e掛在了input_dev 和 input_handler 的h_list上了。通過input_dev 和input_handler就可以找到input_handle在設(shè)備注冊和事件處理器,注冊的時候都要進行配對工作,配對后就會實現(xiàn)鏈接。通過input_handle也可以找到input_dev和input_handler。 我們可以看到,input_device和inp
31、ut_handler中都有一個h_list,而input_handle擁有指向input_dev和input_handler的指針,也就是說input_handle是用來關(guān)聯(lián)input_dev和input_handler的。那么為什么一個input_device和input_handler中擁有的是h_list而不是一個handle呢?因為一個device可能對應(yīng)多個handler,而一個handler也不能只處理一個device,比如說一個鼠標(biāo),它可以對應(yīng)even handler,也可以對應(yīng)mouse handler,因此當(dāng)其注冊時與系統(tǒng)中的handler進行匹配,就有可能產(chǎn)生兩個實例,一個
32、是evdev,另一個是mousedev,而任何一個實例中都只有一個handle。至于以何種方式來傳遞事件,就由用戶程序打開哪個實例來決定。后面一個情況很容易理解,一個事件驅(qū)動不能只為一個甚至一種設(shè)備服務(wù),系統(tǒng)中可能有多種設(shè)備都能使用這類handler,比如event handler就可以匹配所有的設(shè)備。在input子系統(tǒng)中,有8種事件驅(qū)動,每種事件驅(qū)動最多可以對應(yīng)32個設(shè)備,因此dev實例總數(shù)最多可以達到256個。六、輸入系統(tǒng)初始化代碼路徑 kernel/drivers/input/input.c9. static int _init input_init(voi
33、d) 10. 11. int err; 12. 13. err = class_register(&input_class); /注冊類 創(chuàng)建"/sys/input" 14. if (err) 15.
34、60; printk(KERN_ERR "input: unable to register input_dev classn"); 16. return err; 17. 18. 19. &
35、#160; err = input_proc_init(); /初始化"/proc/bus/input"接口 20. if (err) 21. goto fail1; 22. 23.
36、60;err = register_chrdev(INPUT_MAJOR, "input", &input_fops); /注冊所有輸入字符設(shè)備,并捆綁input_fops 24. if (err) 25. printk(KERN_ERR "input: u
37、nable to register char major %d", INPUT_MAJOR); 26. goto fail2; 27. 28. 29. return 0; 30. 31. fail2: input_proc_e
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 廣東大灣區(qū)一模數(shù)學(xué)試卷
- 高考為什么沒有數(shù)學(xué)試卷
- 高三高一數(shù)學(xué)試卷
- 鄂州高考數(shù)學(xué)試卷
- 肝病的識別和治療
- 2025年04月四川樂山市人民醫(yī)院臨床醫(yī)技類招聘60人筆試歷年專業(yè)考點(難、易錯點)附帶答案詳解
- 馬云新人培訓(xùn)課件
- 2024年11月浙江浙商銀行總行授信評審部社會招考(1117)筆試歷年參考題庫附帶答案詳解
- 2024年重慶大學(xué)物理學(xué)院招聘筆試真題
- 2025至2030不銹鋼日用品行業(yè)發(fā)展趨勢分析與未來投資戰(zhàn)略咨詢研究報告
- 雙輪銑攪拌樁施工方案
- DG-TJ 08-2398-2022 纖維增強復(fù)合材料筋混凝土結(jié)構(gòu)技術(shù)標(biāo)準(zhǔn)
- 《公頃和平方千米》(課件)人教版四年級數(shù)學(xué)上冊
- NBT 35095-2017 水電工程小流域水文計算規(guī)范
- 煙葉道路運輸服務(wù)方案
- 胎膜早破護理查房完整版
- 急性左心衰護理查房課件
- 用于生態(tài)修復(fù)的粉煤灰
- 精餾塔設(shè)計方案及流程
- (正式版)JBT 2603-2024 電動懸掛起重機
- (多應(yīng)用場合版)光伏組件外貿(mào)購銷合同-2024
評論
0/150
提交評論