分类: LINUX
2008-08-21 17:03:31
中断驱动程序 包括底层驱动和中断响应程序 #include#include #include #include #include #include #include #include #include #include #include #define DEVICE_NAME "irq4" MODULE_LICENSE("GPL"); int dev_MAJOR; static irqreturn_t at91_interrupt_IRQ4(int irq,void *dev_id, struct pt_regs *regs) /////中断响应程序 { printk("at91rm9200: IRQ4 interrupt success ...\n"); at91_set_gpio_value(AT91_PIN_PA0,1);///将提供下降延的设备复位 置高 return 0; } static int irq4_open(struct inode *inode, struct file *filp) ///中断驱动程序中的open { int ret; unsigned int smr; printk("OPEN...."); smr = at91_sys_read(AT91_AIC_SMR(AT91RM9200_ID_IRQ4)) & ~AT91_AIC_SRCTYPE; at91_sys_write(AT91_AIC_SMR(AT91RM9200_ID_IRQ4), smr | AT91_AIC_SRCTYPE_FALLING); ////对寄存器AIC_SMR,设置中断的属性 上升下降延还是高低电平 这里是下降研 ret = request_irq( AT91RM9200_ID_IRQ4, at91_interrupt_IRQ4, SA_INTERRUPT, DEVICE_NAME, NULL); ////申请中断 printk("ret = %d ...\n",ret); if(ret) printk(KERN_ERR"IRQ %d already in use\n",AT91RM9200_ID_IRQ4); at91_set_B_periph(AT91_PIN_PA2,1); //PA2 - periphB IRQ2点///将IRQ2至高 return ret; } static int irq4_release(struct inode *inode,struct file *filp) { free_irq(AT91RM9200_ID_IRQ4,NULL); /// 释放中断 return 0; } static struct file_operations irq4_fops={ .owner = THIS_MODULE, .open = irq4_open, .release = irq4_release, }; static int __init irq4_init(void) { int ret; ret = register_chrdev(0,DEVICE_NAME,&irq4_fops); if(ret<0) { printk("irq4 can't get the major number...\n"); return ret; } dev_MAJOR = ret; printk("irq4 module init...\n"); return 0; } static void __exit irq4_exit(void) { unregister_chrdev(dev_MAJOR,DEVICE_NAME); } module_init(irq4_init); module_exit(irq4_exit); 总结:这是一个基于at91rm9200芯片的中断驱动程序。利用芯片自带的外部中断源中的一个IRQ2.
本驱动只提供open,close功能。对于中断的申请 request_irq ,可以放在模块init中,
但是这样以来,只要将模块加载进去,中断就开启了,在中断利用较多的情况下是浪费资源的,
所以将中断的申请放在open函数中,打开设备就申请中断。
问题:每次重新启动系统第一次open设备(即申请中断)都会运行一次中断服务程序,之后就正常了
好奇怪。。。。。