一,前言:
1, 近日要寫乙個很特殊的鍵盤驅動,故對linux的input子系統分析了一番,寫下分析筆記,以防不日即忘。
2, 使用input子系統的一般流程為:input_allocate_device()申請乙個input_dev裝置——>初始化該input_dev——>input_register_device()向子系統註冊該裝置——>中斷時input_event()向子系統報告事件。此流程一目了然,即使不看input子系統,我們按照它給出的一般流程也可以把自己寫的io驅動加入到input子系統裡去,但input_event()提交完資料後,我們的資料去哪了呢,怎麼處理呢,總覺得雲裡霧裡的,總想一**竟。
3,此分析基於linux核心:2.6.19.2(linux-2.6.29的核心已經對input子系統有所修改,但基本的思路是一致的)
二:下面給出乙個簡單的驅動,用定時器來模擬中斷來提交鍵盤的事件。
#include
#include
#include
#include
#include
#include
#include
#include
/*! input device structure. */
static struct input_dev *serkbd_dev = null;
static struct timer_list report_timer;
static unsigned short t_interval = 2*hz;
#define keycodes 8
#define press_left_code 30
#define press_right_code 29
#define press_up_code 28
#define press_down_code 27
#define rel_left_code 158
#define rel_right_code 157
#define rel_up_code 156
#define rel_down_code 155
static u16 serkpd_keycodes[keycodes] = else, /* matches all devices */
, /* terminating zero entry */
如英文註解,可以匹配所有的input裝置。故每匹配完乙個裝置就呼叫一次它本身的connect():
static struct input_handle *evbug_connect(struct input_handler *handler, struct input_dev *dev,
const struct input_device_id *id)
struct input_handle *handle;
if (!(handle = kzalloc(sizeof(struct input_handle), gfp_kernel)))
return null;
handle->dev = dev;
handle->handler = handler;
handle->name = evbug_name
input_open_device(handle);
printk(kern_debug "evbug.c: connected device: /"%s/", %s/n", dev->name, dev->phys);
return handle;
這個函式很簡單,它先申請乙個input_handle結構體,然後把dev和handler賦給它,可以想像一下,handle有兩隻手,乙隻手牽著dev,另乙隻手牽著handler,這樣無論是dev還是handler都可以通過handle找到對方。
4,input_open_device()函式定義如下:
int input_open_device(struct input_handle *handle)
struct input_dev *dev = handle->dev;
int err;
err = mutex_lock_interruptible(&dev->mutex);
if (err)
return err;
handle->open++;
if (!dev->users++ && dev->open)
err = dev->open(dev);
if (err)
handle->open--;
mutex_unlock(&dev->mutex);
return err;
函式很簡單,增加open和users計數,如果第一次開啟,就呼叫dev->open,記得我們的測試驅動中的open函式下定義是這樣的:
static int ser_kpp_open(struct input_dev *dev)
return 0;
什麼都沒做,直接返回0.
5, 最後我們看一下evbug.c裡面的event函式。
static void evbug_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
printk(kern_debug "evbug.c: event. dev: %s, type: %d, code: %d, value: %d/n",
handle->dev->phys, type, code, value);
就是input_event()報告事件的時候最終把資料傳到這裡來。這裡只是簡單地把這些資訊輸出來。
四,小結:input_dev在註冊的時候會掛在input_dev_list鍊錶上,然後通過遍歷input_handler_list嘗試匹配已有的每個handler,並把成功匹配的handle掛在dev->h_list鍊錶上,當驅動input_event()報告事件時,就通過dev->h_list鍊錶找到每乙個已匹配的handler,並把事件傳給它們處理。
而與此對應handler註冊時則會把自己掛在input_handler_list上,然後通過遍歷input_dev_list鍊錶,看看有沒有匹配的input_dev, 有則把自己掛在匹配的dev->h_list上。當有事件到來時,input_handler結構體裡面的event函式就可以對事件作處理了。
抓住了這樣乙個主線,整個input子系統的大概來龍去脈就基本清楚了。
下面順便貼一下測試結果:
root@361-21com:/mnt/sd# insmod ser_keyb.ko
input: serkpd as /class/input/input0
ser-keypad init
root@361-21com:/mnt/sd# evbug.c: event. dev: , type: 1, code: 30, value: 1
evbug.c: event. dev: , type: 1, code: 30, value: 0
evbug.c: event. dev: , type: 1, code: 29, value: 1
evbug.c: event. dev: , type: 1, code: 29, value: 0
evbug.c: event. dev: , type: 1, code: 28, value: 1
evbug.c: event. dev: , type: 1, code: 28, value: 0
evbug.c: event. dev: , type: 1, code: 27, value: 1
evbug.c: event. dev: , type: 1, code: 27, value: 0
evbug.c: event. dev: , type: 1, code: 158, value: 1
evbug.c: event. dev: , type: 1, code: 158, value: 0
evbug.c: event. dev: , type: 1, code: 157, value: 1
evbug.c: event. dev: , type: 1, code: 157, value: 0
evbug.c: event. dev: , type: 1, code: 156, value: 1
evbug.c: event. dev: , type: 1, code: 156, value: 0
evbug.c: event. dev: , type: 1, code: 155, value: 1
evbug.c: event. dev: , type: 1, code: 155, value: 0
這兩天頭緒又有點亂,又不知道該幹嗎。其實input的東西遠遠沒有搞明白,但很沒心思搞,抵抗外界干擾的能力太差!
文章出處:
Linux Input子系統 概述
輸入裝置總類繁雜,包括按鍵,鍵盤,觸控螢幕,滑鼠,搖桿等等,它們本身都是字元裝置,不過核心為了能將這些裝置的共性抽象出來,簡化驅動的開發,建立了乙個input子系統。input子系統分為三層,從下至上分別是輸入裝置驅動層,輸入核心層以及輸入事件驅動層。這三層中的輸入核心層和輸入事件驅動層都是核心已經...
Linux INPUT子系統實驗
按鍵 滑鼠 鍵盤 觸控螢幕都屬於輸入裝置,針對這些裝置linux核心提供了乙個叫做input的子系統框架來處理輸入時間,本質上還是字元裝置,只是在此基礎上加上了input框架,使用者只需要負責上報輸入事件,input核心層負責處理這些事件。input子系統分為input驅動層 input核心層 in...
linux input子系統驅動(一)
linux input子系統分析 概述與資料結構 input子系統處理輸入事務,任何輸入裝置的驅動程式都可以通過input輸入子系統提供的介面註冊到核心,利用子系統提供的功能來與使用者空間互動。輸入裝置一般包括鍵盤,滑鼠,觸控螢幕等,在核心中都是以輸入裝置出現的。下面分析input輸入子系統的結構,...