版權所有,轉載請說明轉自 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開發板上的key1和key2編寫按鍵驅動,根據資料知道,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或應用層測試代碼,可以查閱我的博文,鏈接如下