您的位置:首页 > 运维架构 > Linux

OK6410中断按键 混杂设备驱动

2012-04-12 22:34 537 查看
平台:交叉工具链arm-linux-gcc 4.3.2     linux2.6.28

request_irq的作用是申请使用IRQ并注册中断处理程序。

request_irq()函数的原型如下:

/* kernel/irq/manage.c */

int request_irq(

unsigned int irq,

irqreturn_t (*handler)(int, void *, struct pt_regs *),

unsigned long irqflags,

const char *devname,

void *dev_id );

当使用内核共享中断时,request_irq必须要提供dev_id参数,并且dev_id的值必须唯一

将使用该中断处理程序的设备结构体传递给该中断处理程序:

首先看两个基础条件:

1) 内核中的各个设备结构体肯定是唯一的,因此满足dev_id唯一这个要求

2) dev_id参数会在发生中断时传递给该中断的服务程序。

典型的中断服务程序定义如下:

static irqreturn_t intr_handler(int irq, void *dev_id, struct pt_regs *regs);

即request_irq的dev_id参数会传递给该中断服务程序的dev_id。因此也可以将驱动程序的设备结构体通过dev_id传递给中断服务程序。

button1.c 

#include <linux/fs.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <linux/miscdevice.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
#include <mach/hardware.h>
#include <linux/platform_device.h>
//  #include <mach/regs-gpio.h>
//  #include <mach/gpio-bank-n.h>
#include <plat/gpio-cfg.h>

#define DEVICE_NAME "button_irq"

static int button_irq_open(struct inode *inode,struct file *filp)
{
return 0;
}
static int button_irq_release(struct inode *inode,struct file *filp)
{
return 0;
}
static irqreturn_t  button_irq_inter(int nr,void *devid)  //中断处理函数
{
static int count=0;
count ++;
printk("The button1 is sucessed! count= %d\n",count);
return IRQ_RETVAL(IRQ_HANDLED);
}
static int button_irq_init()
{
unsigned int ret;
ret = request_irq(IRQ_EINT(0),button_irq_inter,IRQF_TRIGGER_FALLING,"KEY0",NULL);  //中断请求
if(ret==0)
printk("request_irq was sucessed!\n");
return 0;
}
static struct file_operations dev_fops =
{
.owner = THIS_MODULE,
.open = button_irq_open,
.release = button_irq_release,

};
static struct miscdevice misc =
{
.minor = MISC_DYNAMIC_MINOR,
.name = DEVICE_NAME,
.fops = &dev_fops,
};
static int __init dev_init()
{
int ret=0;
ret = misc_register(&misc);
printk("dev_init return ret:%d\n",ret);
button_irq_init();
return 0;
}
static void __exit dev_exit()
{
misc_deregister(&misc);
free_irq(IRQ_EINT(0),NULL);
}

module_init(dev_init);
module_exit(dev_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("MUGE0913");


Makefile

ifneq ($(KERNELRELEASE),)

obj-m := button1.o

else

KDIR := /home/ok6410/linux2.6.28/linux2.6.28

all:
make -C $(KDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=arm-linux-
clean:
rm -f *.ko *.o *.mod.o *.mod.c *.symvers

endif
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息