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");

实验现象
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43542305/article/details/86239140
今日推荐