日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

[arm 驱动]Linux输入子系统分析

發布時間:2025/3/18 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [arm 驱动]Linux输入子系统分析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

首先說明一下,本文是基于Linux-2.6.38版本內核來分析Linux輸入子系統架構和原理的。這陣子本來沒有打算花時間來分析Linux input system的,然而當在研究S3C6410觸摸屏驅動的時候悲劇不期而至,內核中并沒有實現6410的觸摸屏驅動,不過有關于S3C2410觸摸屏的驅動,往s3c2410_ts.c文件里面一看,居然實現過程中用到了輸入子系統這一神馬機制。瞄了下代碼,流程基本知道了,但是關于輸入子系統的原理是怎樣的呢?全部知其然,好吧,就去了解這一神秘的東東吧!Now。。。

1、為何引入input system?

? ? ? 以前我們寫一些輸入設備(鍵盤、鼠標等)的驅動都是采用字符設備、混雜設備處理的。問題由此而來,Linux開源社區的大神們看到了這大量輸入設備如此分散不堪,有木有可以實現一種機制,可以對分散的、不同類別的輸入設備進行統一的驅動,所以才出現了輸入子系統。

? ? ? 輸入子系統引入的好處:

(1)統一了物理形態各異的相似的輸入設備的處理功能。例如,各種鼠標,不論PS/2、USB、還是藍牙,都被同樣處理。

(2)提供了用于分發輸入報告給用戶應用程序的簡單的事件(event)接口。你的驅動不必創建、管理/dev節點以及相關的訪問方法。因此它能夠很方便的調用輸入API以發送鼠標移動、鍵盤按鍵,或觸摸事件給用戶空間。X windows這樣的應用程序能夠無縫地運行于輸入子系統提供的event接口之上。

(3)抽取出了輸入驅動的通用部分,簡化了驅動,并提供了一致性。例如,輸入子系統提供了一個底層驅動(成為serio)的集合,支持對串口和鍵盤控制器等硬件輸入的訪問。

注:更多詳細描述可參見《精通Linux設備驅動程序開發》這本書。

2、輸入子系統架構

上圖展示了輸入子系統的操作。此子系統包括一前一后運行的兩類驅動:輸入事件(event)驅動輸入設備(device)驅動。

? ? ? ?輸入事件驅動負責和應用程序的接口;

? ? ? ?而輸入設備驅動負責和底層輸入設備的通信。

? ? ? ?輸入事件驅動和輸入設備驅動都可以利用輸入子系統的高效、可重用的核心提供的服務。

? ? ? ?Now,我們看到輸入子系統中有兩個類型的驅動,當我們要為一個輸入設備(如觸摸屏)的編寫驅動的時候,我們是要編寫兩個驅動:輸入設備驅動和輸入事件驅動??

? ? ? 答案是否定的。在子系統中,事件驅動是標準的,對所有的輸入類都是可以用的,所以你更可能的是實現輸入設備驅動而不是輸入事件驅動。你的設備可以利用一個已經存在的,合適的輸入事件驅動通過輸入核心和用戶應用程序接口。

3、主要數據結構和內核編程接口

input_event
include/linux/input.h
evdev產生的每個事件包都采用此格式。

input_dev
include/linux/input.h
代表一個輸入設備。

input_handler
include/linux/serial_core.h
事件驅動支持的入口函數。

psmouse_protocol
drivers/input/mouse/psmouse-base.c
所支持的PS/2鼠標協議驅動相關的信息。

psmouse
drivers/input/mouse/psmouse.h
PS/2鼠標驅動支持的方法。

內核編程接口概述 內核接口位置描述

input_register_device()
drivers/input/input.c
向input核心注冊一個設備。

input_unregister_device()
drivers/input/input.c
從input核心移除一個設備。

input_report_rel()
include/linux/input.h
在某個方向產生相對移動。

input_report_abs()
include/linux/input.h
在某個方向產生絕對移動。

input_report_key()
include/linux/input.h
產生一個按鍵或按鈕按擊。

input_sync()
include/linux/input.h
表明輸入子系統能收集以前產生的事件,將這些事件組成一個evdev包,并通過/dev/input/ inputX發送給用戶空間。

input_register_handler()
drivers/input/input.c
注冊一個用戶事件驅動。

sysfs_create_group()
fs/sysfs/group.c
用特定屬性創建sysfs節點組。

sysfs_remove_group()
fs/sysfs/group.c
移除用sysfs_create_group()創建的sysfs組。

tty_insert_flip_char()
include/linux/tty_flip.h
發送一個字符給線路規程層。

platform_device_register_simple()
drivers/base/platform.c
創建一個簡單平臺設備。

platform_device_unregister()
drivers/base/platform.c
卸載一個平臺設備。


4、輸入設備驅動(注意,以下是結構詳細描述)

在輸入子系統的設備驅動中,最重要的數據結構是struct input_dev,需要完成的大部分工作都是圍繞著它來的,它是驅動的主體。每個struct input_dev代表一個輸入設備。/* include/linux/input.h */

struct input_dev {

? ? ? ? const char *name; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/*設備名 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?*/

? ? ? ? const char *phys; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? ? ? ? const char *uniq;

? struct input_id id; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/*用于匹配事件處理層handler ? */

? ? ? ? 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)]; ? ? ? ? ? ? ? ? ? ? ? ?/*led ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */

? ? ? ? unsigned long sndbit[BITS_TO_LONGS(SND_CNT)]; ? ? ? ? ? ? ? ? ? ? ? /*beep ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */

? ? ? ? unsigned long ffbit[BITS_TO_LONGS(FF_CNT)];

? ? ? ? unsigned long swbit[BITS_TO_LONGS(SW_CNT)];

? ? ? ? unsigned int keycodemax; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /*支持的按鍵值的個數 ? ? ? ? ? ? ? ?*/

? ? ? ? unsigned int keycodesize; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/*每個鍵值的字節數 ? ? ? ? ? ? ? ? ? ?*/

? ? ? ? void *keycode; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /*存儲按鍵值的數組首地址 ? ? ? ? ? ? */

? ? ? ? int(*setkeycode)(struct input_dev *dev, int scancode, int keycode); ? ? ?/* 修改鍵值的函數,可選 ? ? ? ? ? ? */

? ? ? ? int(*getkeycode)(struct input_dev *dev, int scancode, int *keycode); ? ?/* 獲取掃描碼的鍵值,可選 ? ? ? ? */

? ? ? ? structff_device *ff;

? ? ? ? unsigned int repeat_key; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/*最近一次按鍵值,用于連擊 ? ? */

? ? ? ? struct timer_list timer; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/*自動連擊計時器 ? ? ? ? ? ? ? ? ? ? ? ? */

? ? ? ? int sync; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/*最后一次同步后沒有新的事件置1*/

? ? ? ? int abs[ABS_MAX + 1]; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* 當前各個坐標的值 ? ? ? ? ? ? ? ? ? ? ? ? ? ?*/

? ? ? ? int rep[REP_MAX + 1]; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /*自動連擊的參數 ? ? ? ? ? ? ?*/

? ? ? ? unsigned longkey[BITS_TO_LONGS(KEY_CNT)]; ? ? ? ? ? ? ? ? ? ? ? ? ? /*反映當前按鍵狀態的位圖 ? ? ? ?*/

? ? ? ? unsigned long led[BITS_TO_LONGS(LED_CNT)]; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/*反映當前led狀態的位圖 ? ? ? ? ?*/

? ? ? ? unsigned long snd[BITS_TO_LONGS(SND_CNT)]; ? ? ? ? ? ? ? ? ? ? ? ? ? /*反映當前beep狀態的位圖 ? ? ? ?*/

? ? ? ? unsigned long sw[BITS_TO_LONGS(SW_CNT)]; ? ? ? ? ? ? ? ? ? ? ? ? ? ?

? ? ? ? int absmax[ABS_MAX + 1]; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /*記錄各個坐標的最大值 ? ? ? ? ? ?*/

? ? ? ? int absmin[ABS_MAX + 1]; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/*記錄各個坐標的最小值 ? ? ? ? ? ?*/

? ? ? ? int absfuzz[ABS_MAX + 1]; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /*記錄各個坐標的分辨率 ? ? ? ? ? ?*/

? ? ? ? int absflat[ABS_MAX + 1]; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /*記錄各個坐標的基準值 ? ? ? ? ? ?*/

? ? ? ? int(*open)(struct input_dev *dev); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/*打開函數 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */

? ? ? ? void(*close)(struct input_dev *dev); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/*關閉函數 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */

? ? ? ? int(*flush)(struct input_dev *dev, struct file *file); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/* 斷開連接時沖洗數據 ? ? ? ? ? ? ? ? */

? ? ? ? int(*event)(struct input_dev *dev, unsigned int type, unsigned int code, intvalue); /* 回調函數,可選 ? ? ? */

struct input_handle *grab;

? ? ? ? spinlock_t event_lock;

? ? ? ? struct mutex mutex;

? ? ? ? unsigned int users;

? ? ? ? int going_away;

? ? ? ? struct device dev;

? ? ? ? struct list_head ? ?h_list;?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/*handle鏈表 ? ? ? ? ? ? ? ? ? ? ? ? ? */ ? ?

? ? ? ? struct list_head ??node;?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /*input_dev鏈表 ? ? ? ? ? ? ? ? ? ? ? */

};

? ? ? struct input_event是事件傳送的載體,輸入子系統的事件都是包裝成struct input_event傳給用戶空間。??struct input_event成員介紹

/* include/linux/input.h */

struct input_event {

? ? ? ? struct timeval time; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/*時間戳 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */

? ? ? ? __u16 type; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /*事件類型 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */

? ? ? ? __u16 code; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /*事件代碼 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */

? ? ? ? __s32 value; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/*事件值,如坐標的偏移值 ? ? ? ?*/

};

struct input_dev注冊的時候需要跟匹配的hanlder建立連接,匹配的依據就是struct input_dev所包含的struct input_id。

?struct input_id成員描述

/* include/linux/input.h */

struct?input_id?{

? ? ? ? __u16bustype; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/*總線類型 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */

? ? ? ? __u16vendor; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /*生產商編號 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */

? ? ? ? __u16product; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/*產品編號 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */

? ? ? ? __u16version; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?/*版本號 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */

};

5、input_dev成員詳解

1??打開和關閉函數

struct input_dev中有openclose兩個函數指針。在與handler第一次連接之后會調用open函數,斷開連接會調用close。open中應該完成硬件初始化的相關工作,并且申請用到的其他資源,如中斷號。close函數做相反的工作。

2??事件類型

Linux輸入子系統支持的事件類型如下:

/* include/linux/input.h */

#define EV_SYN ? ? ? ? ? ? ? ? ? ? ? ? ? ?0x00 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /*?同步事件 ? ? ? ? ? ? ? ? ? ? ? ? ? ?*/

#define EV_KEY ? ? ? ? ? ? ? ? ? ? ? ? ? ?0x01 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /*按鍵事件 ? ? ? ? ? ? ? ? ? ? ? ? ? ?*/

#define EV_REL ? ? ? ? ? ? ? ? ? ? ? ? ? ?0x02 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /*相對坐標 ? ? ? ? ? ? ? ? ? ? ? ? ? ?*/

#define EV_ABS ? ? ? ? ? ? ? ? ? ? ? ? ? ?0x03 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /*絕對坐標 ? ? ? ? ? ? ? ? ? ? ? ? ? ?*/

#define EV_MSC ? ? ? ? ? ? ? ? ? ? ? ? ? 0x04

#define EV_SW ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?0x05

#define EV_LED ? ? ? ? ? ? ? ? ? ? ? ? ? ?0x11 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /*led ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */

#define EV_SND ? ? ? ? ? ? ? ? ? ? ? ? ? ?0x12 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /*beep ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? */

#define EV_REP ? ? ? ? ? ? ? ? ? ? ? ? ? ?0x14 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? /*連擊事件 ? ? ? ? ? ? ? ? ? ? ? ? ???*/

#define EV_FF ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0x15

#define EV_PWR ? ? ? ? ? ? ? ? ? ? ? ? ? ?0x16

#define EV_FF_STATUS ? ? ? ? ? ? ? ? ? ? ?0x17

#define EV_MAX ? ? ? ? ? ? ? ? ? ? ? ? ? ?0x1f ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?

#define EV_CNT ? ? ? ? ? ? ? ? ? ? ? ? ? ?(EV_MAX+1)

按鍵事件(EV_KEY)是最簡單的事件類型,用來描述按鍵或者按鈕。報告按鍵事件使用以下函數:

input_report_key(struct input_dev *dev, int code, int value)

code的值在<內核>include/linux/input.h中定義,大小從0KEY_MAX。value0時表示按鍵抬起,非0時代表按鍵按下。對同一個按鍵來說,只有當value的值和上次不同才會產生一次事件。

除了按鍵事件,相對坐標事件(EV_REL)和絕對坐標事件(EV_ABS)也是常用的事件。為了使設備支持這兩類事件,需要在初始化時對struct input_devevbit相應比特置1,并且還要分別在relbitabsbit位圖中為支持的坐標軸置1

相對坐標事件用來描述類似鼠標移動的消息。報告相對坐標的函數如下:

input_report_rel(structinput_dev *dev, int code, int value)

? ? ? code描述坐標軸,value代表相對移動(可正可負)。只有當value的值非零時才能產生一個有效的事件。

絕對坐標需要額外的工作。初始化時需要填充input_dev中的一些數據域。對于支持的每個坐標軸調用如下函數:

input_set_abs_params(struct input_dev *dev, int axis,int min, int max, int fuzz, int flat);

函數參數從右往左依次代表輸入設備指針、坐標軸、最小值、最大值、分辨率、基準值。最后兩個參數也可以填為0,代表設備非常精確并且總能精確的回到中心位置。

input_set_abs_params函數的代碼

static inline void input_set_abs_params(structinput_dev *dev, int axis, int min, int max, int fuzz, int flat)

{

? ? ? ? dev->absmin[axis]= min;

? ? ? ? dev->absmax[axis]= max;

? ? ? ? dev->absfuzz[axis]= fuzz;

? ? ? ? dev->absflat[axis]= flat;

? ? ? ? dev->absbit[BIT_WORD(axis)]|= BIT_MASK(axis); ? ? ? ? ? ? ? ? ?

/*?這一行已經注冊了坐標?*/

}

另外輸入設備驅動中經常用到同步事件(EV_SYN),輸入子系統會默認支持此事件,驅動無需注冊。鼠標、觸摸板之類的設備需要用它來提示上層已經發送完了一個完整的事件報告。同步事件的報告形式如下:

input_sync(zlgkpd->input);

3??keycode、?keycodemaxkeycodesize

? ? 首先說明掃描碼和鍵值的區別。如程序清單?1.4<!--[if gte mso 9]><![endif]-->所示,例子中包含四個按鍵的值,那么掃描碼的范圍是0~3,鍵值就是keypad_keycode中的四個值。

keycode、?keycodemaxkeycodesize這三個數據域保存的值分別是鍵值數組的首地址、鍵值的個數和每個鍵值的字節大小。有了這三個變量,就可以在運行是改變鍵盤的鍵值映射。比如原來數組中的第四個鍵值為KEY_Z,可以根據需要改為KEY_D或者其他的值。這樣同樣的掃描碼就對應的不同的鍵值。

這三個域正確填充之后,內核可以使用input_dev的成員函數來修改鍵值映射。修改映射的函數就是input_dev中的setkeycode、getkeycode這兩個函數指針對應的函數,如果注冊之前不初始化它們,則初始化函數把系統默認的函數賦給它們。

EVIOCGKEYCODEEVIOCSKEYCODE這兩個ioctl命令分別用來查看和修改鍵值。

4??按鍵的自動連擊

? ?我們都有這樣的經歷:按住方向鍵不松開,一直把文檔往某個方向拉。這個功能就是自動連擊,也就是在按鍵抬起之前連續發送按鍵事件。

? ?按鍵連擊事件(EV_REP)的開啟非常簡單,在input_devdevbit相應比特置1即可。dev->rep[REP_DELAY]dev->rep[REP_PERIOD]分別存儲連擊的延時和周期,如果驅動不對它們賦值,則系統為他們分別賦為25033。按鍵延時即按鍵到第一次連擊的間隔,按鍵周期即兩次連擊之間的間隔。它們的單位都是毫秒。

5??總線類型

? ?Input_devinput_id用到了總線類型。輸入子系統支持的總線類型如下所示。

/* include/linux/input.h */

#define BUS_PCI ? ? ? ? ? ? ? ? ? ? ? ? ? 0x01

#define BUS_ISAPNP ? ? ? ? ? ? ? ? ? ? ? 0x02

#define BUS_USB ? ? ? ? ? ? ? ? ? ? ? ? ?0x03

#define BUS_HIL ? ? ? ? ? ? ? ? ? ? ? ? ? 0x04

#define BUS_BLUETOOTH ? ? ? ? ? ? ? ? ?0x05

#define BUS_VIRTUAL ? ? ? ? ? ? ? ? ? ? ?0x06

#define BUS_ISA ? ? ? ? ? ? ? ? ? ? ? ? ? 0x10

#define BUS_I8042 ? ? ? ? ? ? ? ? ? ? ? ? 0x11

#define BUS_XTKBD ? ? ? ? ? ? ? ? ? ? ? 0x12

#define BUS_RS232 ? ? ? ? ? ? ? ? ? ? ? ?0x13

#define BUS_GAMEPORT ? ? ? ? ? ? ? ? ? 0x14

#define BUS_PARPORT ? ? ? ? ? ? ? ? ? ? 0x15

#define BUS_AMIGA ? ? ? ? ? ? ? ? ? ? ? ?0x16

#define BUS_ADB ? ? ? ? ? ? ? ? ? ? ? ? ?0x17

#define BUS_I2C ? ? ? ? ? ? ? ? ? ? ? ? ? 0x18

#define BUS_HOST ? ? ? ? ? ? ? ? ? ? ? ? 0x19

#define BUS_GSC ? ? ? ? ? ? ? ? ? ? ? ? 0x1A

#define BUS_ATARI ? ? ? ? ? ? ? ? ? ? ? ?0x1B

6??其他的事件類型

? ? ?EV_LEDEV_SND事件是針對鍵盤上的led和蜂鳴器。這兩類事件是由輸入子系統內核發送給驅動的。

? ? 如果驅動支持這兩類事件的話,應該填充input_dev中的event函數指針,其實這是一個回調函數。另外需要填充input_devevbit對應的比特位。

這個回調函數可能在中斷或者中斷的底半部調用,因此event函數不能睡眠且必須盡快結束。



本文轉自lilin9105 51CTO博客,原文鏈接:http://blog.51cto.com/7071976/1398175,如需轉載請自行聯系原作者

總結

以上是生活随笔為你收集整理的[arm 驱动]Linux输入子系统分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。