实现步骤
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");
实验现象