2014年1月27日 星期一

Linux Input Device - Touchscreen in Android 輸入子系統 part2

在上一篇中,我們介紹了input device在kernel space中的input driver部分。

本篇將繼續介紹剩餘的input core以及event handler




input core

input core是input driver 與event handler之間的媒介,當driver從硬體拿到資料時會透過core所提供的interface轉交給handler處理。因此我們必須把driver與handler透過core關聯起來(match),這樣一來當底層driver有讀取到資料時才能送到對應且正確的handler進行事件處裡。接著將會介紹driver與handler是如何進行match。

input handler

主要負責事件的處理,提供數個call back function,以下介紹兩個function

//處理從driver傳上來的事件,並進行轉換提供給user space
void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);

//將input_dev與handler進行關聯
int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);

touchscreen所使用的handler是drivers/input/evdev.c,下一段將會對evdev做簡單的介紹

input driver、input core與event handler之間的關係
上一篇中提到的touchscreen driver s3c2410_ts.c 所使用的input device相關function都是實作在input core (drivers/input/input.c)。

其中的input_allocate_device()為分配一個記憶體空間給新的input device。

input_register_device()則為註冊一個input device,為了避免占掉太多版面程式碼請參考此連結

其中值得注意的是以下程式碼:

//將剛才配置的input device 加入input_dev_list 之中
list_add_tail(&dev->node, &input_dev_list);

//接下來找尋input_handler_list中的所有的handler,讓input_dev與input_handler進行配對
list_for_each_entry(handler, &input_handler_list, node)
      input_attach_handler(dev, handler);

input_attach_handler之中,主要進行match的是下面這行:

//意思是handler所支援的id table必須有這個device
input_match_device(handler->id_table, dev);

//如果有支援,則呼叫connect將handler及dev關聯起來,並且初始化一個input_handle,代表一組成功關聯的handler及dev
handler->connect(handler, dev, id);

因為connect是call back function,實際的實作程式碼必須要看找到的handler是哪個才能決定,譬如說touchscreen是使用evdev這個handler,所以會對應到evdev_connect()。

p.s.因為我所使用的kernel 版本是3.2,所以下面的程式碼可能因不同版本而有所不同

static int evdev_connect(struct input_handler *handler, struct input_dev *dev, 
                                     const struct input_device_id *id)
{
//初始化
...

//建立/dev/input/event,以提供上層讀取touch的資料
   evdev_install_chrdev(evdev);
   device_add(&evdev->dev);

...
}

另外,關於driver上報點資料時,在handler收到時將會被當成事件來處理,上一篇提到的兩個function input_report_abs()及input_report_key()均被導向至input_event()處理。

每一個事件都有三個參數type、code及value所組成

type:表示事件的類型,定義在include/uapi/linux/input.h,譬如說EV_KEY為按鍵或是按鈕,EV_ABS為絕對座標等等

code:定義該type更詳細的資訊,譬如說第幾個KEY

value:該事件的數值

有了這三個資訊我們便能很詳細的分辨出該事件了。

對於處理點資料的input_event()則是在導向至input_handle_event()對不同type進行處理,最後在使用input_pass_event()填入type、code及value,完成事件的回報。

以上就是對kernel space input device的介紹了

整理了好久@@

Ref:





沒有留言:

張貼留言