如果我們要寫乙個gpio 的按鍵驅動,可以有兩種寫法
1. 寫個字元裝置,利用中斷 ,阻塞讀寫就能實現。
2. 註冊成input 裝置,利用中斷向上報告按鍵。
如果只是測試,第一種寫法是可行的,也更加簡潔,它的優點就在於高效,不依靠輸入子系統。
但是,這種按鍵實現複雜一點的按鍵功能就要寫很多底層**了,而且它有個最大的缺點:上層的介面系統很難友好的使用這種驅動,除非把上層介面系統的按鍵介面做相應的修改。
所以,input 裝置,依靠了輸入子系統,上層介面系統對它的使用很方便了。
input 按鍵驅動的工作機制大概如下:
按鍵產生中斷,在中斷中向上報告鍵值:
這裡要注意兩點:
1. input_event(input, type, button->code, !!state); 這個函式 如果第一次報告了 input_event(input, type, button->code,
1); 第二次又報告了 input_event(input, type, button->code,
1); 那麼第二次是報告不上的,也就是說 只有鍵值變化了報告才有效。這也是按鍵驅動為什麼都是雙邊延觸發,就是為了產生按鍵按下 和 按鍵抬起 ,如果每次只報告一次按鍵按下,那麼 驅動只會報告一次按鍵。
2. 如果 設定了 __set_bit(ev_rep, input->evbit); 也就是重複報告,它的工作機制是這樣的:
如果按鍵報告了input_event(input, type, button->code,
1); 之後, 在250ms (可以改)後,依然沒有報告 input_event(input, type, button->code,
0); 則 input 會每隔 33ms 繼續報告一次 input_event(input, type, button->code,
2); 直到 報告了 input_event(input, type, button->code,
0); 才停止 ,這就是我們按住乙個按鍵不鬆開時,會一直列印鍵值的原因;
這段**在 drivers/input/input.c 中 /**
if delay and period are pre-set by the driver, then autorepeating
* is handled by the driver itself and we don't do it in input.c.
*/init_timer(&dev->timer);
if (!dev->rep[rep_delay] && !dev->rep[rep_period])
這裡要注意紅色的說明文字,也就說如果我們自己的驅動裡自己定義了 dev->rep[rep_delay] = 2500; 那麼就不會使用input 的timer ,而要使用自己編寫的timer 。
linux input子系統驅動(一)
linux input子系統分析 概述與資料結構 input子系統處理輸入事務,任何輸入裝置的驅動程式都可以通過input輸入子系統提供的介面註冊到核心,利用子系統提供的功能來與使用者空間互動。輸入裝置一般包括鍵盤,滑鼠,觸控螢幕等,在核心中都是以輸入裝置出現的。下面分析input輸入子系統的結構,...
Linux input輸入裝置驅動程式
在linux中,輸入子系統是由輸入子系統驅動層,輸入子系統核心層 輸入子系統事件處理層組成。其中,裝置驅動層提供對硬體各暫存器的讀寫訪問和將底層硬體對使用者輸入訪問的響應轉化為標準的輸入事件,再通過核心層提交給事件處理層。而核心層向下提供了裝置驅動層的程式設計介面,向上又提供了事件處理層的程式設計介...
Linux驅動 按鍵驅動
開發板 tiny6410 核心版本 linux2.6.38 要想寫出案件驅動 需要複習的知識 1 混雜裝置的使用原理 2 系統呼叫驅動函式的原理 3 中斷處理機制 4 阻塞性裝置驅動的書寫規範 1 混雜裝置的註冊和使用比較簡單,以前也複習過,這裡不再複習 3 中斷處理機制 也有部落格內容中斷處理機制...