一、input輸入子系統總體框架
linux輸入子系統將輸入驅動抽象為三層:裝置驅動層、核心層、事件處理層。
裝置驅動層:將底層的硬體輸入事件轉化為統一事件形式,向輸入核心(input core)匯報。
核心層:承上啟下。為驅動提供裝置和驅動註冊等操作的函式介面。
事件處理層:和使用者層互動,提供裝置的read和write等函式。
二、輸入子系統的分層分析
2.1 裝置驅動層(使用者編寫)
從輸入子系統的結構框圖,我們可以看出裝置驅動層和硬體聯絡得很緊密。
因為硬體的多樣性,導致裝置驅動層要適應這種多樣性,因此裝置驅動層是易於變化的部分。
編寫輸入子系統驅動的
主要工作就在裝置驅動層
。input子系統的裝置驅動層為了向上遮蔽硬體裝置的差異,將硬體產生的事件統一用
struct input_event來表示。
struct input_event
裝置驅動程式的資料結構
struct input_dev ;
struct input_id ;
裝置驅動層編寫主要內容:
1.為硬體裝置分配乙個
input_dev結構體(使用函式
input_allocate_device)
2.設定
input_dev結構體
支援的事件
set_bit(ev_key, input_dev->evbit)
set_bit(key_enter, buttons_dev->keybit)(支援按鍵型別下的
key_enter
事件)
3.註冊
input_dev結構體
呼叫input_register_device(input_dev)
4.上報事件(一般在中斷函式內)
input_event(input_dev ,type, code, value)
input_sync(input_dev)(上報事件結束);
2.2 核心層(核心自帶)
核心層它主要的就是起過渡作用,這主要體現在input_open_file中;
我們的應用程式使用open函式開啟input裝置檔案,首先呼叫的就是核心層input.c中的
input_open_file
函式。通過該裝置的次裝置號找到與該裝置相關聯的操作函式。
static int input_open_file(struct inode *inode, struct file *file)
file->f_op = new_fops; //將裝置的fops賦值給它的檔案描述符的f_op
err = new_fops->open(inode, file); //呼叫handler->fops->open實現檔案的開啟 }
2.3 事件處理層(核心自帶)
事件處理層主要是為底層的裝置提供讀寫操作的函式,用於和使用者空間進行互動。input子系統使用
struct input_handler
代表裝置的處理方法。
struct input_handler ;
當input_device或
input_handler註冊的時候,如果裝置驅動層的
input_device
和事件處理層的
input_handler有相匹配的話,input子系統就新建乙個
input_handle連聯絡它們。
struct
input_handle ;
2.4 input子系統工作大致流程
input子系統會維護兩個全域性鍊錶: struct input_dev裝置鍊錶,
struct input_handler裝置處理方法鍊錶
input子系統會維護乙個全域性陣列:
static struct input_handler *input_table[8];//按次裝置號儲存裝置處理方法
1.裝置驅動層
裝置驅動層
註冊時呼叫i
nput_register_device
(),該函式完成如下工作:
首先將該
struct input_dev
裝置加入到input子系統的全域性裝置鍊錶中去,然後再分別取出
struct input_handler鍊錶中的每個裝置處理方法
,呼叫input_match_device(handler->id_table, dev)進行裝置和裝置處理方法的匹配,如果匹配成功那麼將新建乙個
struct input_handle來連線
struct input_dev和
struct input_handler。
事件處理層:
2.事件處理層
核心其實都自帶很多的input_handler裝置處理方法,evdev.c,keybroad.c等,它們呼叫i
nput_register_handler
()註冊,該函式完成的工作如下: 首先
會根據註冊的input_handler的次裝置號將它放到乙個
input_table陣列中去,當應用程式開啟某個input裝置節點時,就可以根據它的次裝置號在
input_table陣列中找到它的處理方法。然後將
該struct input_handler
加入到input子系統的全域性裝置處理方法鍊錶中去,
最後再分別取出
struct input_dev鍊錶中的每個裝置
,呼叫input_match_device(handler->id_table, dev)進行裝置和裝置處理方法的匹配,如果匹配成功那麼將新建乙個
struct input_handle來連線
struct input_dev和
struct input_handler。
3. 應用程式的open操作
當應用程式開啟乙個input裝置節點的時候,會根據裝置的次裝置號在input_table陣列裡面選擇它對應的input_handler,然後將該input_handler的檔案操作函式賦給struct file *file。
4.底層的事件發生時
當硬體狀態發生變化時,一般會引起乙個中斷,在這個中斷中通過input_event(dev,type, code, value)向輸入核心層上報事件,這將導致
事件處理層
input_handler
的event(handle,type, code, value)將被呼叫
。那麼使用者層就可以通過呼叫read/write進行裝置讀寫了。
linux驅動 Input 輸入子系統
1,哪些驅動裝置使用驅動子系統更方便簡單?像按鍵,觸控螢幕,滑鼠等輸入裝置我們可以採用input介面函式來實現裝置驅動,那麼採用input輸入子系統有什麼優點?其實一句話,採用input輸入子系統可以使驅動程式變得異常簡單。2,input輸入子系統的體系結構 主要包括三大體系結構 裝置驅動層driv...
Linux裝置驅動 input輸入子系統
不同的輸入裝置 如按鍵 鍵盤 觸控螢幕 滑鼠等 都有它們的差異性 如中斷 讀鍵值 座標值是裝置相關的 及共同性 如輸入事件的緩衝區管理以及字元裝置驅動的file operations介面則對輸入裝置是通用的 因此在linux核心中設計了input輸入子系統來完成輸入裝置之間的共性工作,而我們只需要使...
Linux驅動之input輸入子系統
input輸入子系統在實際專案中用的也比較多,按鍵,觸控螢幕,滑鼠,鍵盤等,用來實現核心層和應用層資料之間的傳遞,這裡得說明不只有input,還有copy to user等,利用input的好處是我們用自己上傳資料到應用程式,我們直接上報這個事件發生了,input自帶的機制會實現上傳的功能。還有很多...