linux輸入子系統——按鍵
阿新 • • 發佈:2019-01-12
實現步驟
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");
實驗現象