S3C2440按键、中断、等待队列

中断

中断注册函数request_irq

request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,const char *name, void *dev)
作用:注册中断服务函数
参数:
	irq:中断名称
	handeler:中断函数名
	flags:宏 IRQF_TRIGGER_FALLING (...)
	name:中断名称(自己起)
	dev:设备名所在

禁止其他中断执行disable_irq()

disable_irq((unsigned int irq)

删除中断函数free_irq()

void free_irq(unsigned int irq, void *dev_id)

等待队列

1.定义一个队列头 数据类型位wait_queue_head_t
2.初始化等待队列头 (使用带参宏init_waitqueue_head(q))
参数:wait_queue_head_t类型变量
3.阻塞wait_event(wq,condition);
condition为假才能进入函数调用

//Linux驱动编程按键(等待队列demo以及中断注册函数)
#include<linux/init.h>
#include<linux/module.h>
#include<linux/fs.h>
#include<linux/miscdevice.h>
#include<asm/uaccess.h>
#include<asm/io.h>
#include<linux/interrupt.h>
#include<mach/irqs.h>
#include<linux/wait.h>
#include<linux/sched.h>
unsigned int *regGPGCON;
unsigned int *regGPGDAT;

static int key;
static wait_queue_head_t wq;
static int condition;
/*static int key_pressed(void)
{
	int ret = 0;
	if(!(*regGPGDAT & 0x01))
	{
		return 1;
	}

	return ret;
}*/

static ssize_t key_device_read(struct file *fp, char __user *puser, size_t len, loff_t *offset)
{
	condition = 0;
	wait_event_interruptible(wq, condition);
	copy_to_user(puser, &key, sizeof(key));
	key = 0;
	return sizeof(key);
}	
int key_device_open(struct inode *pnode, struct file *fp)
{
	return 0;

}
int key_device_release(struct inode *pnode, struct file *fp)
{
	return 0;

}
struct file_operations fops = 
{
	.owner = THIS_MODULE,
	.read = key_device_read,
	.open = key_device_open,
	.release = key_device_release
};

static struct miscdevice key_device =
{
	.minor = MISC_DYNAMIC_MINOR,
	.name = "key",
	.fops = &fops,
};


irqreturn_t key_interrupt(int irq_num, void *dev)
{
	if(irq_num == IRQ_EINT8)
	{
		key = 1;
	}
	condition = 1;
	wake_up_interruptible(&wq);
	return IRQ_HANDLED;
}

static int __init key_driver_init(void)
{
	misc_register(&key_device);
	if(request_irq(IRQ_EINT8, key_interrupt, IRQF_TRIGGER_FALLING | IRQF_DISABLED, "EINT8", &key_device) != 0)
	{
		misc_deregister(&key_device);
		return -1;
	}
	init_waitqueue_head(&wq);
	regGPGCON = ioremap(0x56000060, 4);
	regGPGDAT = ioremap(0x56000064, 4);
	*regGPGCON &= ~(0x03 << 0);
	*regGPGCON |= (0x01 << 1);
	return 0;
}

static void __exit key_driver_exit(void)
{
	iounmap(regGPGCON);
	iounmap(regGPGDAT);
	disable_irq(IRQ_EINT8);
	free_irq(IRQ_EINT8, &key_device);
	misc_deregister(&key_device);
}
module_init(key_driver_init);
module_exit(key_driver_exit);
MODULE_LICENSE("GPL");

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值