⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 buttons.c

📁 linux下按键的驱动
💻 C
字号:
#include <linux/module.h>
//#include <linux/delay.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <asm/hardware.h>
#include <asm/uaccess.h>
#include <asm/arch/S3C2410.h>
#include <asm/arch/irqs.h>


#define DEVICE_NAME "buttons"
#define BUTTON_MAJOR 0

static int buttonsMajor=0;
int key_value=1;
int ready=0;
static int uptime;
static int downtime;
/*定义按键所使用的cpu资源*/
static struct key_info{
	int irq_no;
	unsigned int gpio_port;
	int key_no;
}key_info_tab[2]={
	{IRQ_EINT0,GPIO_F0,0},
	{IRQ_EINT11,GPIO_G3,5},
};

/*
static int led_open(struct inode *inode,struct file  *file)
{
	
	MOD_INC_USE_COUNT;
	return 0;
}
static int led_close(struct inode *inode,struct file *file)
{
	MOD_DEC_USE_COUNT;
	leds_event(led_start);
	return 0;
}
*/
static void buttons_irq(int irq,void *dev_id,struct pt_regs *reg)
{
	struct key_info *k;
	int i;
	int found=0;
	int up;
	int flags;
	//使用irq号码判断是否是某个键盘,因为中断程序被4个按键中断共用
	for(i=0;i<sizeof(key_info_tab)/sizeof(key_info_tab[1]);i++)
	{
		k=key_info_tab+i;
		if(k->irq_no==irq)
		{
			found=1;
			break;
		}
	}
	if(!found)
	{
		printk("not found irq %d",irq);
		return;
	}
	save_flags(flags);//保存当前中断状态
	cli();//置位cpsr,禁用中断//???????????????????????????
	//set_gpio_mode_user(k->gpio_port,GPIO_MODE_IN);//复位中断端口,从端口读取电平高低值
	up=read_gpio_bit(k->gpio_port);
	set_external_irq(k->irq_no,EXT_BOTH_EDGES,GPIO_PULLUP_DIS);
	restore_flags(flags);//恢复中断状态
	//保存从中断读出的值
	if(!up)
	{		
		key_value=0;
		downtime = jiffies;
	}
	else
	{
		if(irq==IRQ_EINT0) key_value=1;
		if(irq==IRQ_EINT11) key_value=2;
		uptime=jiffies;
		if((uptime-downtime)>=50) //key_value=3;
		{
			if(irq==IRQ_EINT0) key_value=11;
			if(irq==IRQ_EINT11) key_value=22;
		}
	}
	ready=1;//置位全局状态
	//???????????????????????????????????????????????????????????????????????
	//wake_up_interruptible(&buttons_wait);//等待任务唤醒,select调用的进程
}
static int request_irqs(void)
{
	struct key_info *k;
	int i;
	for(i=0;i<sizeof(key_info_tab)/sizeof(key_info_tab[1]);i++)
	{
		k=key_info_tab+i;
		set_external_irq(k->irq_no,EXT_BOTH_EDGES,GPIO_PULLUP_DIS);
		if(request_irq(k->irq_no,&buttons_irq,SA_INTERRUPT,DEVICE_NAME,&buttons_irq))
		{
			return -1;
		}
	}
	return 0;
}
static void free_irqs(void)
{
	struct key_info *k;
	int i;
	for(i=0;i<sizeof(key_info_tab)/sizeof(key_info_tab[1]);i++)
	{
		k=key_info_tab+i;
		free_irq(k->irq_no,buttons_irq);
	}
}
static int buttons_read(struct file *file,char *buffer,size_t count,loff_t *ppos)
{
	static int key;
	int flags;
	int repeat;
	if(!ready) return -EAGAIN;
	if(count!=sizeof(key_value)) return -EINVAL;
	save_flags(flags);
	if(key!=key_value)
	{
		key=key_value;
		repeat=0;
	}
	else
	{
		repeat=1;
	}
	restore_flags(flags);
	if(repeat)
	{
		return -EAGAIN;
	}
	copy_to_user(buffer,&key,sizeof(key));
	ready=0;
	return sizeof(key_value);
}

static struct file_operations buttons_fops=
{
    owner:      THIS_MODULE,
    read:       buttons_read,
};

static devfs_handle_t devfs_handle,devfs_buttons_dir;
static int __init buttons_init(void)
{
	int ret;
	ready=0;
	ret=register_chrdev(BUTTON_MAJOR,DEVICE_NAME,&buttons_fops);
	if(ret<0)
	{
		printk(DEVICE_NAME "can't register major number\n");
		return ret;
	}
	ret=request_irqs();
	if(ret)
	{
		unregister_chrdev(BUTTON_MAJOR,DEVICE_NAME);
		//printk(DEVICE_NAME "can't register irqs\n);
		return ret;
	}
	ret=devfs_register_chrdev(BUTTON_MAJOR,DEVICE_NAME,&buttons_fops);
	if(ret<0)
	{
		return ret;
	}
	if(!BUTTON_MAJOR)
	{
		buttonsMajor=ret;
		printk("major number=%d\n",buttonsMajor);
	}
    devfs_buttons_dir=devfs_mk_dir(NULL,DEVICE_NAME,NULL);
	devfs_handle=devfs_register(devfs_buttons_dir,"1",DEVFS_FL_DEFAULT,ret,0,S_IFCHR|S_IRUSR|S_IWUSR,&buttons_fops,NULL);
	return 0;
}
static void __exit buttons_exit(void)
{
	int res;
	res=unregister_chrdev(buttonsMajor,DEVICE_NAME);
	devfs_unregister(devfs_handle);
	devfs_unregister(devfs_buttons_dir);
	free_irqs();
}
module_init(buttons_init);
module_exit(buttons_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -