1. 程式人生 > >linux輸入子系統——按鍵

linux輸入子系統——按鍵

轉載linux之輸入子系統分析

實現步驟

1、定義、分配一個input-dev結構體
static struct input_dev *buttons_dev;
buttons_dev=input_allocate_device();

2、設定
buttons_dev->name=“keys”;//名字隨便
set_bit(EV_KEY,buttons_dev->evbit);//按鍵類事件
。。。。
set_bit(KEY_L,buttons_dev->keybit);//該類操作中產生哪些按鍵
。。。

3、註冊
input_register_device(buttons_dev);
input_unregister_device(buttons_dev);//解除安裝

通過開發板上的按鍵實現L、S、回車、空格鍵。

#include <linux/module.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/pm.h>
#include <linux/sysctl.h>
#include
<linux/proc_fs.h>
#include <linux/delay.h> #include <linux/platform_device.h> #include <linux/input.h> #include <linux/irq.h> #include <asm/gpio.h> #include <asm/io.h> static struct input_dev *buttons_dev; static struct timer_list buttons_timer;//定義timer結構體 static
struct pin_desc *irq_pd; struct pin_desc{ int irq; char *name; unsigned int pin;//引腳 unsigned int key_val;//鍵值 }; struct pin_desc pins_desc[4]={ {IRQ_EINT0, "S2", S3C2410_GPF(0), KEY_L}, {IRQ_EINT2, "S3", S3C2410_GPF(2), KEY_S}, {IRQ_EINT11, "S4", S3C2410_GPG(3), KEY_ENTER}, {IRQ_EINT19, "S5", S3C2410_GPG(11), KEY_LEFTSHIFT}, }; static int buttons_irq (int irq, void *dev_id) { /* 10ms後確定按鍵值 */ irq_pd = (struct pin_desc *)dev_id; mod_timer(&buttons_timer, jiffies+HZ/100); return IRQ_RETVAL(IRQ_HANDLED); } static int buttons_timer_func (unsigned long data) { struct pin_desc *pindesc= irq_pd; unsigned int pinval; if (!pindesc)//時間到達時,沒有產生中斷 return -1; pinval=s3c2410_gpio_getpin(pindesc->pin);//讀引腳 if(pinval)//1 鬆開 { input_event(buttons_dev,EV_KEY,pindesc->key_val,0); input_sync(buttons_dev); } else//按下 input_event(buttons_dev,EV_KEY,pindesc->key_val,1);//上傳資料 input_sync(buttons_dev);//資料同步結束 } int major; static int new_drv_init(void) { /*1分配一個input-dev結構體*/ buttons_dev=input_allocate_device(); buttons_dev->name="keys"; /*2設定*/ set_bit(EV_KEY,buttons_dev->evbit);//按鍵類事件 set_bit(EV_REP,buttons_dev->evbit);//支援重複類事件,按鍵長按 set_bit(KEY_L,buttons_dev->keybit);//改類操作中產生哪些按鍵 set_bit(KEY_S,buttons_dev->keybit); set_bit(KEY_ENTER,buttons_dev->keybit); set_bit(KEY_LEFTSHIFT,buttons_dev->keybit); /*3註冊*/ input_register_device(buttons_dev); /*4硬體相關操作*/ init_timer(&buttons_timer);//初始化timer buttons_timer.function = buttons_timer_func;//超時時間到了,進入定時處理函式 add_timer(&buttons_timer); int i; for(i=0;i<4;i++) { /* 中斷引腳 中斷函式 觸發方式 名稱 傳入dev?id */ request_irq(pins_desc[i].irq,buttons_irq,(IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING),pins_desc[i].name,&pins_desc[i]); } return 0; } static void new_drv_exit(void) { int i; for(i=0;i<4;i++) { /* 中斷引腳 傳入dev?id */ free_irq(pins_desc[i].irq,&pins_desc[i]); } del_timer(&buttons_timer); input_unregister_device(buttons_dev); input_free_device(buttons_dev);//釋放結構體 } module_init(new_drv_init);//入口函式 module_exit(new_drv_exit);//出口函式 MODULE_LICENSE("GPL");

實驗現象
在這裡插入圖片描述