首頁體育 > 正文

Linux input子系統分析之二 相關資料結構及其關聯建立說明

2021-11-08由 資訊聯絡員 發表于 體育

在上一章我們介紹了input子系統的總體框架,本章則主要說明input相關的資料結構結構,以及這些資料結構之間的關聯。對於linux核心而言,只要我們理解了其資料結構之間的關聯,基本上也就大致瞭解其子系統的實現。

一、input子系統資料結構及其關聯

針對input子系統而言,其資料結構主要包括input_device、input_handler、input_handle,其中input_dev用於對一個input device的抽象,而一個input_handler則可以理解為對一個input device的驅動,但是和裝置驅動模型子系統的device_driver、device還是有所區別的。

input_device、input_handler、input_handle的關聯

我們先從整體上熟悉下這三個資料結構之間的關聯,如下圖所示:

透過vfs層、字元裝置檔案節點層,應用程式可以對input裝置進行訪問操作;

input裝置相關的字元裝置操作介面,可透過呼叫input_inject_event向input dev下發事件(如控制led燈的亮滅);同時在input_dev上報event時,會呼叫input_handler的event/events介面,而在該接口裡則wakeup 字元裝置讀操作的wait佇列,字元裝置讀介面從而進行事件的讀取(如input dev接收到按鍵按下事件);

所有註冊到系統的input_handler,均連結至連結串列input_handler_list;

所有註冊到系統的input_device,均連結至連結串列input_dev_list;

input_handle完成input_handler、input_dev的間接關聯(一般在input_handler的connect介面中呼叫input_register_handle實現這種間接關聯)

Linux input子系統分析之二 相關資料結構及其關聯建立說明

Input device與input handler的多對多繫結模型實現

在input子系統中,一個input_device可以對應多個input_handler,而一個input_handler也可以對應多個input_device;而在裝置驅動模型中,一個device僅對應一個driver,而一個driver可對應多個同類型的device。在input子系統中,為了完成input_handler、input_device的多對多的特性,其抽象了一個input_handle資料結構,該資料結構用於管理input_handler、input_device,但input_handler與input_device之間沒有直接管理。藉助input_handle,一個input_device上可以關聯多個input_handle,從而完成對多個input_handler的關聯;而一個input_handler亦可以關聯多個input_handle,從而完成對多個input_device的關聯。

input device與inputhandler的事件分發機制

針對input_device可以透過input_event介面將event事件分發給該input_device上所有的input_handle,進而傳送給input_handler;同時input_handler可以透過input_inject_event將event事件分發給該input_handler上所有的input_handle,進而傳送給input_device。

這種事件分發機制,可以理解為訊息訂閱機制,與linux下的通知鏈機制類似。其實input_register_handler、input_register_device可以理解為訊息的訂閱,而input_event、input_inject_event則為訊息的分發。

input_handler資料結構

Input_handler可以理解為input_device的方法/驅動,下面我們詳細說明;

event、events介面用於接收input_device分發的事件,並處理這些事件(如將這些事件傳送給應用程式);

filter介面進行事件過濾檢測;

input_handler內部的match檢測介面,一般使用input子系統提供的input_match_device介面即可,此指標可不賦值;

connect、disconnect這兩個介面用於input_device、input_handler連線建立與釋放時,呼叫的介面,類似於裝置驅動模型中的probe、remove;

legacy_minors為true表示使用該handler定義好的字元裝置次裝置起始值及範圍,一般一個handler支援的字元裝置個數為32個,在3。10及之前的核心中,input子系統註冊了統一的字元裝置操作介面,然後該字元裝置操作介面,再呼叫具體handler註冊的操作介面;而在新3。10以後的核心中,inout子系統則不再註冊字元裝置操作介面(僅申請input子系統的字元裝置區間),由各handler自行註冊字元裝置及其操作介面;

id_table指示該input_handler支援的input_device id,input_device_id包括匯流排型別、廠商id、裝置id、版本號、evbit、keybit、relbit、absbit、mscbit、ledbit、sndbit、ffbit、swbit、propbit等,input_match_device_id介面則根據這些引數用於判斷input_device、input_handler是否匹配;

h_list用於連結該handler繫結的input_handle。當需要向該input_handler關聯的所有input_device傳送事件時,則遍歷該連結串列找到每一個input_dev,並呼叫其event介面,由input_dev進行處理。

Linux input子系統分析之二 相關資料結構及其關聯建立說明

input_dev資料結構說明

Input_dev的定義如下,主要包括如下幾個部分:

evbit、keybit、relbit、absbit等變數標識該input device的型別、支援事件的code型別等;

keycode相關的引數及函式指標等;

open、event、close、flush為操作介面,如針對event則處理input_handler傳送的事件,一般input裝置而言,都是input_dev將接收的事件傳送給input_handler,而針對led燈這類裝置,需要處理input_handler傳送的event,用於進行led燈的控制;

users、going_away為該input device的開啟及關聯相關的引用計數及狀態;

num_vals、max_vals、vals、hint_events_per_packet則表示該input_dev單次分發事件時可傳送的最大事件數、當前事件數、儲存待分發事件的快取等內容;

針對grab變數。其實現input_device與input_handle的1對1繫結操作,若執行了該操作,則所有該input_device產生的事件,則只分發給其繫結的input_handle對應的input_handler,而不再分發給其他的input_handler。若需要執行該繫結操作,則透過EVIOCGRAB ioctl命令即可設定。

Linux input子系統分析之二 相關資料結構及其關聯建立說明

input_handle資料結構說明

該資料結構主要用於關聯input_dev、input_handler,其定義如下,該資料結構定義簡單,不再細述。

Linux input子系統分析之二 相關資料結構及其關聯建立說明

以上即為input子系統主要資料結構及其關聯說明,而我們理解這三個資料結構的關聯,input子系統的input_register_handler、input_register_handle、input_register_device不過是建立資料結構間的關聯罷了。我們熟悉了上面的關係圖後,再去理解input子系統的實現,會簡單很多,下一章節將介紹input_register_handler、input_register_handle、input_register_device以及事件的分發處理介面input_event、input_inject_event等。

頂部