Linux下的Keyboard子系统
版權(quán)所有,轉(zhuǎn)載請(qǐng)說明轉(zhuǎn)自 http://my.csdn.net/weiqing1981127
?
最簡(jiǎn)單的按鍵驅(qū)動(dòng)就是一個(gè)中斷處理函數(shù),當(dāng)用戶有按鍵,通過read函數(shù)向應(yīng)用層上報(bào)按鍵信息。而我們這里講的keyboard子系統(tǒng),主要是對(duì)按鍵進(jìn)行了分裝和優(yōu)化,這里我們主要講的是可以實(shí)現(xiàn)跨平臺(tái)的按鍵驅(qū)動(dòng)。不管你是使用三星的平臺(tái),還是Atmel的平臺(tái),你只要知道如何在你的BSP中添加平臺(tái)數(shù)據(jù),并且知道如何在應(yīng)用程序中使用這個(gè)驅(qū)動(dòng),那么你就不用因?yàn)樾碌钠脚_(tái)而再次編寫按鍵驅(qū)動(dòng)了。
?
按鍵驅(qū)動(dòng)屬于input子系統(tǒng),源碼路徑在/driver/input/keyboard下,我們的跨平臺(tái)按鍵驅(qū)動(dòng)文件是/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
所以配置內(nèi)核make menuconfig時(shí),需要選中這一項(xiàng)。
?
現(xiàn)在先來看如何移植,比如我們現(xiàn)在要給mini2440開發(fā)板上的key1和key2編寫按鍵驅(qū)動(dòng),根據(jù)資料知道,key1用的是GPG0端口,key2用的是GPG3端口。下面就看移植代碼了,在mach-mini2440.c這個(gè)mini2440開發(fā)板的BSP中添加如下代碼
static struct gpio_keys_button s3c_buttons[] = {
?????? {
????????????? .code???????????? = KEY_LEFT,??? //鍵值,驅(qū)動(dòng)人員可自己設(shè)定,但用戶必須知道
????????????? .gpio????????????? = S3C2410_GPG(0),
????????????? .active_low???? = 1,????????? //下降沿觸發(fā)方式
????????????? .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,
?????? }
};
然后把這個(gè)s3c_button_device加入到mini2440_devices數(shù)組
static struct platform_device *mini2440_devices[] __initdata = {
?????? ……
?????? &s3c_button_device, //添加
};
最后添加頭文件
#include <linux/gpio.h>
#include <linux/gpio_keys.h>
這樣配置完后,進(jìn)行make zImage生成zImage內(nèi)核鏡像。
?
下面大致說說/driver/input/keyboard/Gpio_keys.c
static struct platform_driver gpio_keys_device_driver = {
?????? .probe??????????? = gpio_keys_probe,?? //探測(cè)
?????? .remove????????? = __devexit_p(gpio_keys_remove),
?????? .driver??????????? = {
????????????? .name????? = "gpio-keys",?? //驅(qū)動(dòng)名
????????????? .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); //平臺(tái)驅(qū)動(dòng)注冊(cè)
}
關(guān)于這個(gè)Gpio_keys.c的其他代碼在此就不看了,總結(jié)下,probe函數(shù)主要是申請(qǐng)端口,然后注冊(cè)中斷,并將其放在input子系統(tǒng)中。當(dāng)用戶有按鍵時(shí),觸發(fā)按鍵中斷服務(wù)程序,進(jìn)行一些簡(jiǎn)單數(shù)據(jù)處理后交給底半部,由工作隊(duì)列完成向input子系統(tǒng)上報(bào)鍵值的操作,同時(shí)設(shè)計(jì)了定時(shí)器,目的是為了能更加精確報(bào)告按鍵事件。我在學(xué)習(xí)input子系統(tǒng)的時(shí)候,就是拿了一個(gè)按鍵寫入了input子系統(tǒng)中,也用到了工作隊(duì)列和定時(shí)器,跟Gpio_keys.c代碼原理類似,如果需要可以參考。
?
Keyboard驅(qū)動(dòng)測(cè)試
用戶可以先通過cat? /sys/class/input/input0/name判斷input設(shè)備名
然后應(yīng)用層通過訪問/dev/input/event0來讀取按鍵,接著利用訪問input設(shè)備格式判斷鍵值區(qū)分不同的按鍵是否被按下。
?
如果了解Gpio_keys.c或應(yīng)用層測(cè)試代碼,可以查閱我的博文,鏈接如下
?http://blog.csdn.net/weiqing1981127/article/details/8147368
總結(jié)
以上是生活随笔為你收集整理的Linux下的Keyboard子系统的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux下的RTC子系统
- 下一篇: Linux下的压缩文件剖析