平台:交叉工具鏈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