欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
Linux輸入子系統分析

 轉自http://blog.csdn.net/colorant/archive/2007/04/12/1561837.aspx

 

1 輸入子系統架構Overview

        輸入子系統(Input Subsystem)的架構如下圖所示

 

        輸入子系統由 輸入子系統核心層( Input Core ),驅動(dòng)層和事件處理層(Event Handler)三部份組成。一個(gè)輸入事件,如鼠標移動(dòng),鍵盤(pán)按鍵按下,joystick的移動(dòng)等等通過(guò) Driver -> InputCore -> Eventhandler -> userspace 的順序到達用戶(hù)空間傳給應用程序。
        其中Input Core 即 Input Layer 由 driver/input/input.c及相關(guān)頭文件實(shí)現。對下提供了設備驅動(dòng)的接口,對上提供了Event Handler層的編程接口。

1.1 主要數據結構

                                                                                                                          表 1     Input Subsystem main data structure

數據結構

用途

定義位置

具體數據結構的分配和初始化

Struct input_dev

驅動(dòng)層物理Input設備的基本數據結構

Input.h

通常在具體的設備驅動(dòng)中分配和填充具體的設備結構

Struct Evdev

Struct Mousedev

Struct Keybdev…

Event Handler層邏輯Input設備的數據結構

Evdev.c

Mousedev.c

Keybdev.c

Evdev.c/Mouedev.c …中分配

 

Struct Input_handler

Event Handler的結構

Input.h

Event Handler層,定義一個(gè)具體的Event Handler。

Struct Input_handle

用來(lái)創(chuàng )建驅動(dòng)層DevHandler鏈表的鏈表項結構

Input.h

Event Handler層中分配,包含在Evdev/Mousedev…中。

 

1.2 輸入子系統架構示例圖

圖2  輸入子系統架構示例圖


2 輸入鏈路的創(chuàng )建過(guò)程

        由于input子系統通過(guò)分層將一個(gè)輸入設備的輸入過(guò)程分隔為獨立的兩部份:驅動(dòng)到Input Core,Input Core到Event Handler。所以整個(gè)鏈路的這兩部分的接口的創(chuàng )建是獨立的。

2.1 硬件設備的注冊

        驅動(dòng)層負責和底層的硬件設備打交道,將底層硬件對用戶(hù)輸入的響應轉換為標準的輸入事件以后再向上發(fā)送給Input Core。
        驅動(dòng)層通過(guò)調用Input_register_device函數和Input_unregister_device函數來(lái)向輸入子系統中注冊和注銷(xiāo)輸入設備。
這兩個(gè)函數調用的參數是一個(gè)Input_dev結構,這個(gè)結構在driver/input/input.h中定義。驅動(dòng)層在調用Input_register_device之前需要填充該結構中的部分字段

#include <linux/input.h>
#include <linux/module.h>
#include <linux/init.h>

MODULE_LICENSE("GPL");

struct input_dev ex1_dev;

static int __init ex1_init(void)
{
    /* extra safe initialization */
    memset(&ex1_dev, 0, sizeof(struct input_dev));
    init_input_dev(&ex1_dev);

    /* set up descriptive labels */
    ex1_dev.name = "Example 1 device";
    /* phys is unique on a running system */
    ex1_dev.phys = "A/Fake/Path";
    ex1_dev.id.bustype = BUS_HOST;
    ex1_dev.id.vendor = 0x0001;
    ex1_dev.id.product = 0x0001;
    ex1_dev.id.version = 0x0100;
   
    /* this device has two keys (A and B) */
    set_bit(EV_KEY, ex1_dev.evbit);
    set_bit(KEY_B, ex1_dev.keybit);
    set_bit(KEY_A, ex1_dev.keybit);
   
    /* and finally register with the input core */
    input_register_device(&ex1_dev);
   
    return 0;
}

        其中比較重要的是evbit字段用來(lái)定義該輸入設備可以支持的(產(chǎn)生和響應)的事件的類(lèi)型。
包括:

Ø EV_RST   0x00  Reset
Ø EV_KEY   0x01  按鍵
Ø EV_REL   0x02  相對坐標
Ø EV_ABS   0x03  絕對坐標
Ø EV_MSC   0x04  其它
Ø EV_LED   0x11   LED
Ø EV_SND   0x12  聲音
Ø EV_REP   0x14  Repeat
Ø EV_FF   0x15  力反饋

一個(gè)設備可以支持一個(gè)或多個(gè)事件類(lèi)型。每個(gè)事件類(lèi)型下面還需要設置具體的觸發(fā)事件,比如EV_KEY事件,支持哪些按鍵等。

2.2 Event Handler層

2.2.1 注冊Input Handler

        驅動(dòng)層只是把輸入設備注冊到輸入子系統中,在驅動(dòng)層的代碼中本身并不創(chuàng )建設備結點(diǎn)。應用程序用來(lái)與設備打交道的設備結點(diǎn)的創(chuàng )建由Event Handler層調用Input core中的函數來(lái)實(shí)現。而在創(chuàng )建具體的設備節點(diǎn)之前,Event Handler層需要先注冊一類(lèi)設備的輸入事件處理函數及相關(guān)接口
        以MouseDev Handler為例:

static struct input_handler mousedev_handler = {
 event:  mousedev_event,
 connect:  mousedev_connect,
 disconnect: mousedev_disconnect,
 fops:  &mousedev_fops,
 minor:  MOUSEDEV_MINOR_BASE,
};

static int __init mousedev_init(void)
{
 input_register_handler(&mousedev_handler);

 memset(&mousedev_mix, 0, sizeof(struct mousedev));z
 init_waitqueue_head(&mousedev_mix.wait);
 mousedev_table[MOUSEDEV_MIX] = &mousedev_mix;
 mousedev_mix.exist = 1;
 mousedev_mix.minor = MOUSEDEV_MIX;
 mousedev_mix.devfs = input_register_minor("mice", MOUSEDEV_MIX, MOUSEDEV_MINOR_BASE);

 printk(KERN_INFO "mice: PS/2 mouse device common for all mice\n");

 return 0;
}

        在Mousedev_init中調用input.c中定義的input_register_handler來(lái)注冊一個(gè)鼠標類(lèi)型的Handler. 這里的Handler不是具體的用戶(hù)可以操作的設備,而是鼠標類(lèi)設備的統一的處理函數接口。

2.2.2 設備節點(diǎn)的創(chuàng )建

        接下來(lái),mousedev_init函數調用input_register_minor注冊一個(gè)通用mice設備,這才是與用戶(hù)相關(guān)聯(lián)的具體的設備接口。然而這里在init函數中創(chuàng )建一個(gè)通用的Mice設備只是鼠標類(lèi)Event Handler層的特例。在其它類(lèi)型的EventHandler層中,并不一定會(huì )創(chuàng )建一個(gè)通用的設備。
        標準的流程見(jiàn)是硬件驅動(dòng)向Input子系統注冊一個(gè)硬件設備后,在input_register_device中調用已經(jīng)注冊的所有類(lèi)型的Input Handler的connect函數,每一個(gè)具體的Connect函數會(huì )根據注冊設備所支持的事件類(lèi)型判斷是否與自己相關(guān),如果相關(guān)就調用input_register_minor創(chuàng )建一個(gè)具體的設備節點(diǎn)。

void input_register_device(struct input_dev *dev)
{
 ……
 while (handler) {
  if ((handle = handler->connect(handler, dev)))
   input_link_handle(handle);
  handler = handler->next;
 }
}

        此外如果已經(jīng)注冊了一些硬件設備,此后再注冊一類(lèi)新的Input Handler,則同樣會(huì )對所有已注冊的Device調用新的Input Handler的Connect函數已確定是否需要創(chuàng )建新的設備節點(diǎn):

void input_register_handler(struct input_handler *handler)
{
……
 while (dev) {
  if ((handle = handler->connect(handler, dev)))
   input_link_handle(handle);
  dev = dev->next;
 }
}

        從上面的分析中可以看到一類(lèi)Input Handler可以和多個(gè)硬件設備相關(guān)聯(lián),創(chuàng )建多個(gè)設備節點(diǎn)。而一個(gè)設備也可能與多個(gè)Input Handler相關(guān)聯(lián),創(chuàng )建多個(gè)設備節點(diǎn)。
        直觀(guān)起見(jiàn),物理設備,Input Handler,邏輯設備之間的多對多關(guān)系可見(jiàn)下圖:

圖3  物理設備,Input Handler,邏輯設備關(guān)系圖

3 設備的打開(kāi)和讀寫(xiě)

    用戶(hù)程序通過(guò)Input Handler層創(chuàng )建的設備節點(diǎn)的Open,read,write等函數打開(kāi)和讀寫(xiě)輸入設備。

3.1 Open

    設備節點(diǎn)的Open函數,首先會(huì )調用一類(lèi)具體的Input Handler的Open函數,處理一些和該類(lèi)型設備相關(guān)的通用事務(wù),比如初始化事件緩沖區等。然后通過(guò)Input.c中的input_open_device函數調用驅動(dòng)層中具體硬件設備的Open函數。

3.2 Read

    大多數Input Handler的Read函數等待在Event Layer層邏輯設備的wait隊列上。當設備驅動(dòng)程序通過(guò)調用Input_event函數將輸入以事件的形式通知給輸入子系統的時(shí)候,相關(guān)的Input Handler的event函數被調用,該event函數填充事件緩沖區后將等待隊列喚醒。
    在驅動(dòng)層中,讀取設備輸入的一種可能的實(shí)現機制是掃描輸入的函數睡眠在驅動(dòng)設備的等待隊列上,在設備驅動(dòng)的中斷函數中喚醒等待隊列,而后掃描輸入函數將設備輸入包裝成事件的形式通知給輸入子系統。

3.3 Write

    2.4內核中沒(méi)有固定的模式,根據具體的Input Handler,可能不實(shí)現,也可能通過(guò)調用Input_event將寫(xiě)入的數據以事件的形式再次通知給輸入子系統,或者調用設備驅動(dòng)的Write函數等等。
    2.6內核的代碼中,通過(guò)調用Input_event將寫(xiě)入的數據以事件的形式再次通知給輸入子系統,而后在Input.c中根據事件的類(lèi)型,將需要反饋給物理設備的事件通過(guò)調用物理設備的Event函數傳給設備驅動(dòng)處理,如EV_LED事件:

void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value)
{
 ......
 case EV_LED:
         if (code > LED_MAX || !test_bit(code, dev->ledbit) || !!test_bit(code, dev->led) == value)
            return;

         change_bit(code, dev->led);
         if (dev->event) dev->event(dev, type, code, value);
         break;
 ......
 }

4 其它

    本文中對Input子系統架構的分析主要是基于2.4.20內核,在2.6內核中對Input子系統做了很大的擴充增加了對許多設備的支持(如觸摸屏,鍵盤(pán)等)。不過(guò)整體的框架還是一致的。

    另,參考了linux journal上的兩篇文章:

The Linux USB Input Subsystem, Part I | Linux Journal
Using the Input Subsystem, Part II | Linux Journal

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
虛擬鍵盤(pán)、虛擬鼠標驅動(dòng)
Linux input子系統分析
linux輸入子系統
linux input 子系統分析 三
六、2.6內核輸入子系統分析-續 - 輸入子系統:鍵盤(pán)/按鍵/觸摸屏等 - LinuxSm...
【驅動(dòng)】input子系統整體流程全面分析(觸摸屏驅動(dòng)為例)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久