标题:tq2440 按键驱动 中断方式(转)
作者:fly0418
日期:2016-01-18 16:21
内容:
硬件平台:TQ2440
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define DEVICE_NAME "key-device"
MODULE_DESCRIPTION("759981398@qq.com");
MODULE_AUTHOR("traveler");
MODULE_LICENSE("Dual BSD/GPL");
//声明一个等待队列
static DECLARE_WAIT_QUEUE_HEAD(keys_wait_irq) ;
//事件 用于同步用户与驱动程序之间的数据
static volatile int key_event = 0;
//存储按键的值
static volatile int key_value = 0;
static void * key_devid = (void *)0;
//ISR中断服务程序
static irqreturn_t keys_irq(int irq,void *devid)
{
int down ;
//GPIO的 基址 虚拟地址
//对 GPIO的所有操作 都以此地址 作为 参考 地址
const unsigned int gpio_base = (unsigned int )S3C24XX_VA_GPIO;
//获取 GPFDAT寄存器 的 虚拟地址
const unsigned int gpfdat = gpio_base + 16 * 5 + 4;
if(devid!=key_devid)
{
printk("DRIVER ERROR !devid=%dn",(int)devid);
return IRQ_RETVAL(IRQ_NONE);
}
//获取按键引脚状态
down = (*(unsigned int *)gpfdat) ;
//如果当前值和存储的值不相等 则唤醒等待队列
// if((down &0x01) != (key_value&0x01))
{
key_value = down & 0x01;
key_event = 1;
wake_up_interruptible(&keys_wait_irq);
}
//返回标志 中断已服务
return IRQ_RETVAL(IRQ_HANDLED);
}
//读取 按键 状态 用户 调用 参数 列表
static ssize_t key_read(struct file *filp,char __user *buf,
size_t count,loff_t *loff)
{
int err;
if(!key_event)
{
//如果事件未发生并且文件不允许阻塞,那么返回一个错误标识
if(filp->f_flags & O_NONBLOCK)
return -EAGAIN ;
//等待事件
wait_event_interruptible(keys_wait_irq,key_event);
}
//拷贝数据到用户空间
err = copy_to_user(buf,(void*)(&key_value),min(sizeof(key_value ..