歡迎關(guān)注,每周更新!?
本合集分享的是,我當(dāng)初學(xué)習(xí)Linux驅(qū)動的來時路——《《驅(qū)動之路》開篇:自序&前言》。
正文
回答3個問題:
(1)什么是 Input 子系統(tǒng)?
(2)為什么需要 Input 子系統(tǒng)?
(3)如何使用 Input 子系統(tǒng)?
1 什么是 Input 子系統(tǒng)?
Input 子系統(tǒng)是 Linux 內(nèi)核中一套統(tǒng)一管理輸入設(shè)備的框架,主要是為了將鍵盤、鼠標(biāo)、觸摸屏、按鍵、搖桿等各類輸入設(shè)備的硬件差異抽象化,為上層應(yīng)用提供統(tǒng)一的輸入事件接口(如/dev/input/eventX),這樣可以避免為每種設(shè)備單獨編寫驅(qū)動程序。一句話總結(jié)其作用:“屏蔽硬件差異、提供統(tǒng)一接口”。
2 為什么需要 Input 子系統(tǒng)?
假如沒有 Input 子系統(tǒng),想要使用一個輸入設(shè)備,我們需要為每一種設(shè)備單獨編寫完整的驅(qū)動程序,包括硬件初始化、數(shù)據(jù)讀取、事件解析等所有邏輯。這是由于每個輸入設(shè)備(比如 USB 鍵盤、GPIO 按鍵、I2C 觸摸屏、紅外遙控器)的通信協(xié)議、數(shù)據(jù)格式、觸發(fā)方式都不同。
另外,每新增一種輸入設(shè)備(如新型觸摸屏)時,不僅要編寫全新驅(qū)動,還可能與現(xiàn)有設(shè)備沖突,甚至需要修改上層應(yīng)用才能適配。這樣不僅導(dǎo)致 Linux 內(nèi)核代碼冗余嚴(yán)重,而且開發(fā)成本和維護(hù)成本極高。
面對以上種種問題,"封裝"與"分層"這兩大經(jīng)典的程序設(shè)計思想再次發(fā)威,Input 子系統(tǒng)正是基于這樣思想設(shè)計出來解決以上問題的。
Input 子系統(tǒng)有如下主要作用:
硬件差異屏蔽:不同輸入設(shè)備的通信協(xié)議(如 USB、I2C、SPI、GPIO)和數(shù)據(jù)格式不同,Input 子系統(tǒng)通過統(tǒng)一的驅(qū)動模型,將底層硬件細(xì)節(jié)封裝,上層無需關(guān)心設(shè)備是 USB 鍵盤還是 GPIO 按鍵;
統(tǒng)一事件接口:所有輸入設(shè)備最終都通過 /dev/input/eventX節(jié)點暴露給用戶空間,應(yīng)用程序可通過標(biāo)準(zhǔn)的 read ()/poll () 等系統(tǒng)調(diào)用讀取事件(如按鍵按下 / 松開、坐標(biāo)移動、手勢等);
事件標(biāo)準(zhǔn)化:定義了統(tǒng)一的事件類型(如 EV_KEY、EV_ABS、EV_REL)和事件碼(如 KEY_0、ABS_X),確保不同設(shè)備的事件格式一致,上層應(yīng)用可跨設(shè)備兼容。
3 如何使用 Input 子系統(tǒng)?
要想正確使用 Input 子系統(tǒng),不得不理清其3 層架構(gòu):事件處理層、核心層以及驅(qū)動層。核心源代碼位于/drivers/input/目錄。
事件處理層(evdev.c):接收核心層轉(zhuǎn)發(fā)的事件,為上層應(yīng)用提供訪問接口(如/dev/input/eventX設(shè)備節(jié)點)。
核心層(input.c):管理所有輸入設(shè)備,提供驅(qū)動注冊 / 注銷接口,轉(zhuǎn)發(fā)驅(qū)動層事件到合適的事件層。
驅(qū)動層(輸入設(shè)備驅(qū)動程序,如gpio_keys.c 等):直接操作硬件(如 GPIO 中斷、讀取電平),將硬件信號轉(zhuǎn)換為 “標(biāo)準(zhǔn)化輸入事件”。從底層硬件到上層應(yīng)用鏈路如下:

從硬件底層到用戶空間數(shù)據(jù)是如何層層傳遞的?假如用戶空間直接訪問/dev/input/event0設(shè)備節(jié)點,數(shù)據(jù)的流程大致如下:
(1)用戶空間應(yīng)用程序通過read()系統(tǒng)調(diào)用讀取/dev/input/eventX設(shè)備節(jié)點。如果此時內(nèi)核輸入緩沖區(qū)中沒有可用的事件數(shù)據(jù),該read()調(diào)用會使應(yīng)用程序進(jìn)入休眠狀態(tài),等待數(shù)據(jù)到達(dá)。
(2)當(dāng)用戶進(jìn)行操作(如觸摸屏幕、按下按鍵)時,輸入設(shè)備的硬件會產(chǎn)生一個中斷信號(例如,觸摸芯片的中斷引腳電平發(fā)生變化)。
(3)當(dāng)驅(qū)動程序檢測到這個電平時,輸入系統(tǒng)驅(qū)動層對應(yīng)的驅(qū)動程序會調(diào)用中斷處理函數(shù):讀取到數(shù)據(jù),轉(zhuǎn)換為標(biāo)準(zhǔn)的輸入事件,向核心層匯報。
(4)Input核心層接收到事件后,會根據(jù)設(shè)備和事件的類型,上報事件層——將其分發(fā)給已注冊并匹配的事件處理器(Input Handler),例如evdev_handler。當(dāng)用戶空間正在等待數(shù)據(jù)時,evdev_handler會把它喚醒,這樣用戶空間就可以獲取到硬件底層的上報數(shù)據(jù)。
最后,了解下用戶空間獲得數(shù)據(jù)的兩種方法:
直接訪問設(shè)備節(jié)點(比如/dev/input/event0,1,2,...);
通過tslib、libinput 這類庫來間接訪問設(shè)備節(jié)點,這些庫簡化了對數(shù)據(jù)的處理。
如果想繼續(xù)深入理解 Input 子系統(tǒng)是如何將不同輸入設(shè)備的硬件差異統(tǒng)一成標(biāo)準(zhǔn)的輸入事件?請聽下回分解。
(完)
本人專注 Linux 驅(qū)動 & Linux/Android BSP 開發(fā)調(diào)試,可接外包項目/技術(shù)支持/問題定位。有需求或交個朋友可加微信:【Chen_WeChat2026】。
審核編輯 黃宇
-
驅(qū)動
+關(guān)注
關(guān)注
12文章
1957瀏覽量
88566 -
Linux
+關(guān)注
關(guān)注
88文章
11764瀏覽量
219099
發(fā)布評論請先 登錄
迅為RK3568開發(fā)板驅(qū)動指南GPIO子系統(tǒng)GPIO子系統(tǒng)API函數(shù)的引入
迅為RK3568驅(qū)動指南GPIO子系統(tǒng) GPIO操作函數(shù)實驗
RK3568驅(qū)動指南|第十二篇 GPIO子系統(tǒng)-第135章 GPIO子系統(tǒng)與pinctrl子系統(tǒng)相結(jié)合實驗
迅為RK3568驅(qū)動指南GPIO子系統(tǒng)實戰(zhàn):實現(xiàn)動態(tài)切換引腳復(fù)用功能
驅(qū)動之路#10:淺談 Input 子系統(tǒng)
評論