Input輸入子系統(tǒng)分析_第1頁
Input輸入子系統(tǒng)分析_第2頁
Input輸入子系統(tǒng)分析_第3頁
Input輸入子系統(tǒng)分析_第4頁
Input輸入子系統(tǒng)分析_第5頁
已閱讀5頁,還剩6頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、input子系統(tǒng)分析Jason一、概述在linux下,按鍵、觸摸屏、鼠標(biāo)等都可以利用input接口函數(shù)來實(shí)現(xiàn)設(shè)備驅(qū)動(dòng)。1,linux輸入子系統(tǒng)主要分三層: 驅(qū)動(dòng),輸入CORE, 事件處理層。驅(qū)動(dòng)根據(jù)CORE提供的接口,向上報(bào)告發(fā)生的按鍵動(dòng)作。然后CORE根據(jù)驅(qū)動(dòng)的類型,分派這個(gè)報(bào)告給對(duì)應(yīng)的事件處理層進(jìn)行處事。事件處理層把數(shù)據(jù)變化反應(yīng)到設(shè)備模型的文件中(事件緩沖區(qū))。并通知在這些設(shè)備模型文件上等待的進(jìn)程。2,輸入子系統(tǒng)在KERNEL初始化時(shí)被初始化。會(huì)創(chuàng)建所有類型輸入輸出設(shè)備的邏輯設(shè)備(及sysfs結(jié)點(diǎn))。當(dāng)硬件注冊(cè)時(shí),就會(huì)調(diào)用所有類型的input handler的connect函數(shù),根據(jù)硬件注

2、冊(cè)的結(jié)構(gòu)來判斷是否與自己相關(guān),然后再創(chuàng)建一個(gè)具體的設(shè)備結(jié)點(diǎn)。3,驅(qū)動(dòng)只負(fù)責(zé)的把輸入設(shè)備注冊(cè)到輸入子系統(tǒng)中,然后輸入子系統(tǒng)來創(chuàng)建對(duì)應(yīng)的具體設(shè)備結(jié)點(diǎn)。而事件處理層,在初始化時(shí),需要注冊(cè)所一類設(shè)備的輸入事件處理函數(shù)及相關(guān)接口4,一類input handler可以和多個(gè)硬件設(shè)備相關(guān)聯(lián),創(chuàng)建多個(gè)設(shè)備節(jié)點(diǎn)。而一個(gè)設(shè)備也可能與多個(gè)input handler相關(guān)聯(lián),創(chuàng)建多個(gè)設(shè)備節(jié)點(diǎn)。二、輸入設(shè)備結(jié)構(gòu)體1.input_dev 這是input設(shè)備基本的設(shè)備結(jié)構(gòu),每個(gè)input驅(qū)動(dòng)程序中都必須分配初始化這樣一個(gè)結(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 總線類型;廠商編號(hào),產(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);   /相對(duì)位移事件標(biāo)志位  10.     unsigned long absbitBIT

6、S_TO_LONGS(ABS_CNT);   /絕對(duì)位移事件標(biāo)志位  11.     unsigned long mscbitBITS_TO_LONGS(MSC_CNT);   /雜項(xiàng)事件標(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); /強(qiáng)制反饋事件  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;   /強(qiáng)制反饋設(shè)備  28.     unsigned int repeat_key;    /重復(fù)按鍵標(biāo)志位  29.     struct timer_list 

13、;timer;    /定時(shí)器  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),代表一個(gè)事件處理器代碼路徑 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è)備號(hào)  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)體代表一個(gè)成功配對(duì)的input_dev和input_handler代碼路徑 kernel/include/linux/input.hstruct input_handle  1.  

27、   void *private; /每個(gè)配對(duì)的事件處理器都會(huì)分配一個(gè)對(duì)應(yīng)的設(shè)備結(jié)構(gòu),如evdev事件處理器的evdev結(jié)構(gòu),注意這個(gè)結(jié)構(gòu)與設(shè)備驅(qū)動(dòng)層的input_dev不同,初始化handle時(shí),保存到這里。 2.     int open; /打開標(biāo)志,每個(gè)input_handle 打開后才能操作,這個(gè)一般通過事件處理器的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. ; 五、三個(gè)數(shù)據(jù)結(jié)構(gòu)之間的關(guān)系input_dev 是硬件驅(qū)動(dòng)層,代表一個(gè)input設(shè)備input_handler 是事件處理層,代表一個(gè)事件處理器input_handle 個(gè)人認(rèn)為屬于核心層,代表一個(gè)配對(duì)的input設(shè)備與input事件處理器input_dev 通過全局的input_dev_list鏈接在一起。設(shè)備注冊(cè)的時(shí)候?qū)崿F(xiàn)這個(gè)操作。input_handler 通過全局的input_hand

30、ler_list鏈接在一起。事件處理器注冊(cè)的時(shí)候?qū)崿F(xiàn)這個(gè)操作(事件處理器一般內(nèi)核自帶,一般不需要我們來寫)input_hande 沒有一個(gè)全局的鏈表,它注冊(cè)的時(shí)候?qū)⒆约悍謩e掛在了input_dev 和 input_handler 的h_list上了。通過input_dev 和input_handler就可以找到input_handle在設(shè)備注冊(cè)和事件處理器,注冊(cè)的時(shí)候都要進(jìn)行配對(duì)工作,配對(duì)后就會(huì)實(shí)現(xiàn)鏈接。通過input_handle也可以找到input_dev和input_handler。     我們可以看到,input_device和inp

31、ut_handler中都有一個(gè)h_list,而input_handle擁有指向input_dev和input_handler的指針,也就是說input_handle是用來關(guān)聯(lián)input_dev和input_handler的。那么為什么一個(gè)input_device和input_handler中擁有的是h_list而不是一個(gè)handle呢?因?yàn)橐粋€(gè)device可能對(duì)應(yīng)多個(gè)handler,而一個(gè)handler也不能只處理一個(gè)device,比如說一個(gè)鼠標(biāo),它可以對(duì)應(yīng)even handler,也可以對(duì)應(yīng)mouse handler,因此當(dāng)其注冊(cè)時(shí)與系統(tǒng)中的handler進(jìn)行匹配,就有可能產(chǎn)生兩個(gè)實(shí)例,一個(gè)

32、是evdev,另一個(gè)是mousedev,而任何一個(gè)實(shí)例中都只有一個(gè)handle。至于以何種方式來傳遞事件,就由用戶程序打開哪個(gè)實(shí)例來決定。后面一個(gè)情況很容易理解,一個(gè)事件驅(qū)動(dòng)不能只為一個(gè)甚至一種設(shè)備服務(wù),系統(tǒng)中可能有多種設(shè)備都能使用這類handler,比如event handler就可以匹配所有的設(shè)備。在input子系統(tǒng)中,有8種事件驅(qū)動(dòng),每種事件驅(qū)動(dòng)最多可以對(duì)應(yīng)32個(gè)設(shè)備,因此dev實(shí)例總數(shù)最多可以達(dá)到256個(gè)。六、輸入系統(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); /注冊(cè)類 創(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);   /注冊(cè)所有輸入字符設(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等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論