linux input子系統分析--概述與資料結構
input子系統處理輸入事務,任何輸入裝置的驅動程式都可以通過input輸入子系統提供的介面註冊到核心,利用子系統提供的功能來與使用者空間互動。輸入裝置一般包括鍵盤,滑鼠,觸控螢幕等,在核心中都是以輸入裝置出現的。下面分析input輸入子系統的結構,以及功能實現。
一. input子系統結構與功能實現
1. input子系統是分層結構的,總共分為三層: 硬體驅動層,子系統核心層,事件處理層。
(1)其中硬體驅動層負責操作具體的硬體裝置,這層的**是針對具體的驅動程式的,需要驅動程式的作者來編寫。
(2)子系統核心層是鏈結其他兩個層之間的紐帶與橋梁,向下提供驅動層的介面,向上提供事件處理層的介面。
(3)事件處理層負責與使用者程式打交道,將硬體驅動層傳來的事件報告給使用者程式。
2. 各層之間通訊的基本單位就是事件,任何乙個輸入裝置的動作都可以抽象成一種事件,如鍵盤的按下,觸控螢幕的按下,滑鼠的移動等。事件有三種屬性:型別(type),編碼(code),值(value),input子系統支援的所有事件都定義在input.h中,包括所有支援的型別,所屬型別支援的編碼等。事件傳送的方向是 硬體驅動層-->子系統核心-->事件處理層-->使用者空間
3. 以觸控螢幕為例說明輸入子系統的工作流程:
注:mini2440的觸控螢幕驅動所用驅動層對應的模組檔案為:s3c2410_ts.c,事件處理層對應的模組檔案為 evdev.c
(1)s3c2410_ts模組初始化函式中將觸控螢幕註冊到了輸入子系統中,於此同時,註冊函式在事件處理層煉表中尋找事件處理器,這裡找到的是evdev,並且將驅動與事件處理器掛載。並且在/dev/input中生成裝置檔案event0,以後我們訪問這個檔案就會找的我們的觸控螢幕驅動程式。
(2)應用程式開啟裝置檔案/dev/input/event0,讀取裝置檔案,呼叫evdev模組中read,如果沒有事件程序就會睡眠。
(3)當觸控螢幕按下,驅動層通過子系統核心將事件(就是x,y座標),傳給事件處理層也就是evdev,evdev喚醒睡眠的程序,將事件傳給程序處理。
二.主要input通用資料結構
1.input_dev 這是input裝置基本的裝置結構,每個input驅動程式中都必須分配初始化這樣乙個結構,成員比較多
(1)有以下幾個陣列:
[cpp]view plain
copy
unsigned
long
evbit[bits_to_longs(ev_cnt)];
//事件支援的型別
// 下面是每種型別支援的編碼
unsigned long
keybit[bits_to_longs(key_cnt)];
//按鍵
unsigned long
relbit[bits_to_longs(rel_cnt)];
unsigned long
absbit[bits_to_longs(abs_cnt)];
//絕對座標,其中觸控螢幕驅動使用的就是這個
unsigned long
mscbit[bits_to_longs(msc_cnt)];
unsigned long
ledbit[bits_to_longs(led_cnt)];
unsigned long
sndbit[bits_to_longs(snd_cnt)];
unsigned long
ffbit[bits_to_longs(ff_cnt)];
unsigned long
swbit[bits_to_longs(sw_cnt)];
evbit[bits_to_longs(ev_cnt)]; 這個陣列以位掩碼的形式,代表了這個裝置支援的事件的型別。設定方式如:
dev->evbit[0] = bit(ev_syn) | bit(ev_key) | bit(ev_abs)
absbit[bits_to_longs(abs_cnt)]; 這個陣列也是以位掩碼的形式,代表這個型別的事件支援的編碼
觸控螢幕驅動支援ev_abs,所以要設定這個陣列, 有乙個專門設定這個陣列的函式input_set_abs_params,**如下:
[cpp]view plain
copy
static
inline
void
input_set_abs_params(
struct
input_dev *dev,
intaxis,
intmin,
intmax,
intfuzz,
intflat)
觸控螢幕驅動中是這樣呼叫的
input_set_abs_params(dev, abs_x, 0, 0x3ff, 0, 0); //這個是設定ad轉換的x座標
input_set_abs_params(dev, abs_y, 0, 0x3ff, 0, 0); //這個是設定ad轉換的y座標
input_set_abs_params(dev, abs_pressure, 0, 1, 0, 0); //這個是設定觸控螢幕是否按下的標誌
設定abs_x編碼值範圍為0-0x3ff,因為mini2440的ad轉換出的資料最大為10位,所以不會超過0x3ff。
(2) struct input_id id 成員
這個是標識裝置驅動特徵的
[cpp]view plain
copy
struct
input_id ;
如果需要特定的事件處理器來處理這個裝置的話,這幾個就非常重要,因為子系統核心是通過他們,將裝置驅動與事件處理層聯絡起來的。但是因為觸控螢幕驅動所用的事件處理器為evdev,匹配所有,所有這個初始化
也無關緊要。
(3) 還有其他一些成員,也比較重要,但是驅動程式可以不用管,都是由子系統核心來處理的。
(4) 可以看出input_dev 結構所屬層為硬體驅動層,以後就用input_dev來表示輸入裝置。
2. input_handler 這是事件處理器的資料結構,代表乙個事件處理器
(1)幾個操作函式
void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);
void (*disconnect)(struct input_handle *handle);
void (*start)(struct input_handle *handle);
event 函式是當事件處理器接收到了來自input裝置傳來的事件時呼叫的處理函式,負責處理事件,非常重要,在事件傳遞過程中會詳細分析。
connect 函式是當乙個input裝置模組註冊到核心的時候呼叫的,將事件處理器與輸入裝置聯絡起來的函式,也就是將input_dev和input_handler配對的函式。
disconnect 函式實現connect相反的功能。
start 暫時沒有發現有什麼作用。
(2) 兩個id
const struct input_device_id *id_table; //這個是事件處理器所支援的input裝置
const struct input_device_id *blacklist; //這個是事件處理器應該忽略的input裝置
這兩個陣列都會用在connect函式中,input_device_id結構與input_id結構類似,但是input_device_id有乙個flag,用來讓程式選擇比較哪項,如:busytype,vendor還是其他。
(3) 兩個鍊錶
struct list_head
h_list; //這個鍊錶用來鏈結他所支援的input_handle結構,input_dev與input_handler配對之後就會生成乙個input_handle結構
struct list_head
node; //鏈結到input_handler_list,這個鍊錶鏈結了所有註冊到核心的事件處理器
(4) 其他的成員一看**就知道是什麼意思,這裡就不說明了。
3. input_handle 結構體代表乙個成功配對的input_dev和input_handler
[cpp]view plain
copy
struct
input_handle ;
4. 三個資料結構之間的關係
input_dev 是硬體驅動層,代表乙個input裝置
input_handler 是事件處理層,代表乙個事件處理器
input_handle 個人認為屬於核心層,代表乙個配對的input裝置與input事件處理器
input_dev 通過全域性的input_dev_list鏈結在一起。裝置註冊的時候實現這個操作。
input_handler 通過全域性的input_handler_list鏈結在一起。事件處理器註冊的時候實現這個操作(事件處理器一般核心自帶,一般不需要我們來寫)
input_hande 沒有乙個全域性的鍊錶,它註冊的時候將自己分別掛在了input_dev 和 input_handler 的h_list上了。通過input_dev 和input_handler就可以找到input_handle 在裝置註冊和事件處理器, 註冊的時候都要進行配對工作,配對後就會實現鏈結。通過input_handle也可以找到input_dev和input_handler。
Linux Input子系統 概述
輸入裝置總類繁雜,包括按鍵,鍵盤,觸控螢幕,滑鼠,搖桿等等,它們本身都是字元裝置,不過核心為了能將這些裝置的共性抽象出來,簡化驅動的開發,建立了乙個input子系統。input子系統分為三層,從下至上分別是輸入裝置驅動層,輸入核心層以及輸入事件驅動層。這三層中的輸入核心層和輸入事件驅動層都是核心已經...
Linux INPUT子系統實驗
按鍵 滑鼠 鍵盤 觸控螢幕都屬於輸入裝置,針對這些裝置linux核心提供了乙個叫做input的子系統框架來處理輸入時間,本質上還是字元裝置,只是在此基礎上加上了input框架,使用者只需要負責上報輸入事件,input核心層負責處理這些事件。input子系統分為input驅動層 input核心層 in...
linux input 子系統例項分析
一,前言 1,近日要寫乙個很特殊的鍵盤驅動,故對linux的input子系統分析了一番,寫下分析筆記,以防不日即忘。2,使用input子系統的一般流程為 input allocate device 申請乙個input dev裝置 初始化該input dev input register device...