Linux下的Keyboard子系統

版權所有,轉載請說明轉自 http://my.csdn.net/weiqing1981127

 

最簡單的按鍵驅動就是一箇中斷處理函數,當用戶有按鍵,通過read函數嚮應用層上報按鍵信息。而我們這裏講的keyboard子系統,主要是對按鍵進行了分裝和優化,這裏我們主要講的是可以實現跨平臺的按鍵驅動。不管你是使用三星的平臺,還是Atmel的平臺,你只要知道如何在你的BSP中添加平臺數據,並且知道如何在應用程序中使用這個驅動,那麼你就不用因爲新的平臺而再次編寫按鍵驅動了。

 

按鍵驅動屬於input子系統,源碼路徑在/driver/input/keyboard下,我們的跨平臺按鍵驅動文件是/driver/input/keyboard/Gpio_keys.c

查看/driver/input/keyboard/Makefile

obj-$(CONFIG_KEYBOARD_GPIO)           += gpio_keys.o

查看/driver/input/keyboard//Konfig

config KEYBOARD_GPIO

       tristate "GPIO Buttons"

       depends on GENERIC_GPIO

所以配置內核make menuconfig時,需要選中這一項。

 

現在先來看如何移植,比如我們現在要給mini2440開發板上的key1key2編寫按鍵驅動,根據資料知道,key1用的是GPG0端口,key2用的是GPG3端口。下面就看移植代碼了,在mach-mini2440.c這個mini2440開發板的BSP中添加如下代碼

static struct gpio_keys_button s3c_buttons[] = {

       {

              .code             = KEY_LEFT,    //鍵值,驅動人員可自己設定,但用戶必須知道

              .gpio              = S3C2410_GPG(0),

              .active_low     = 1,          //下降沿觸發方式

              .desc              = "key1",

       },

       {

              .code             = KEY_RIGHT,

              .gpio              = S3C2410_GPG(3),

              .active_low     = 1,

              .desc              = "key2",

       },

 

};

 

static struct gpio_keys_platform_data s3c_button_data = {

       .buttons   = s3c_buttons,

       .nbuttons = ARRAY_SIZE(s3c_buttons),

};

 

static struct platform_device s3c_button_device = {

       .name             = "gpio-keys",

       .id           = -1,

       .num_resources     = 0,

       .dev        = {

              .platform_data = &s3c_button_data,

       }

};

然後把這個s3c_button_device加入到mini2440_devices數組

static struct platform_device *mini2440_devices[] __initdata = {

       ……

       &s3c_button_device, //添加

};

最後添加頭文件

#include <linux/gpio.h>

#include <linux/gpio_keys.h>

這樣配置完後,進行make zImage生成zImage內核鏡像。

 

下面大致說說/driver/input/keyboard/Gpio_keys.c

static struct platform_driver gpio_keys_device_driver = {

       .probe            = gpio_keys_probe,   //探測

       .remove          = __devexit_p(gpio_keys_remove),

       .driver            = {

              .name      = "gpio-keys",   //驅動名

              .owner    = THIS_MODULE,

#ifdef CONFIG_PM

              .pm  = &gpio_keys_pm_ops,  //電源管理

#endif

       }

};

static int __init gpio_keys_init(void)

{

       return platform_driver_register(&gpio_keys_device_driver); //平臺驅動註冊

}

關於這個Gpio_keys.c的其他代碼在此就不看了,總結下,probe函數主要是申請端口,然後註冊中斷,並將其放在input子系統中。當用戶有按鍵時,觸發按鍵中斷服務程序,進行一些簡單數據處理後交給底半部,由工作隊列完成向input子系統上報鍵值的操作,同時設計了定時器,目的是爲了能更加精確報告按鍵事件。我在學習input子系統的時候,就是拿了一個按鍵寫入了input子系統中,也用到了工作隊列和定時器,跟Gpio_keys.c代碼原理類似,如果需要可以參考。

 

Keyboard驅動測試

用戶可以先通過cat  /sys/class/input/input0/name判斷input設備名

然後應用層通過訪問/dev/input/event0來讀取按鍵,接着利用訪問input設備格式判斷鍵值區分不同的按鍵是否被按下。

 

如果瞭解Gpio_keys.c或應用層測試代碼,可以查閱我的博文,鏈接如下

 http://blog.csdn.net/weiqing1981127/article/details/8147368

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章