阅读:1203回复:3
一个比较怪的中断程序,大家帮帮忙
以下的是一个完整的驱动程序模块,根据ldd2的short改编的, 编译通过, 加载成功, 加载后读/proc/interrupts 文件发现程序成功注册了irq号, 第一次触发中断时,程序有反应,有输出信息,第二次触发中断时,就不会打印任何东西了,而且rmmod的时候会有问题,请大家多多帮忙
谢谢! //linux 内核版本: 2.4.19 //---------------------------------------------------------------- #ifndef __KERNEL__ # define __KERNEL__ #endif #ifndef MODULE # define MODULE #endif #include <linux/config.h> #include <linux/module.h> #include <linux/sched.h> #include <linux/kernel.h> /* printk() */ #include <linux/fs.h> /* everything... */ #include <linux/errno.h> /* error codes */ #include <linux/delay.h> /* udelay */ #include <linux/slab.h> #include <linux/mm.h> #include <linux/ioport.h> #include <linux/interrupt.h> #include <linux/tqueue.h> #include <asm/io.h> #include "sysdep.h" #define SHORT_NR_PORTS 2 #define base 0x08000010 static int major=0;//dynamic by default static unsigned int blr_mask=0; static unsigned int blr_mask_org=0; static unsigned int status=0; static void * short_base; volatile int short_irq = -1; static int i=0; int short_i_open (struct inode *inode, struct file *filp) { return 0; } int short_i_release (struct inode *inode, struct file *filp) { return 0; } struct file_operations short_i_fops = { open: short_i_open, release: short_i_release, }; void short_tl_interrupt(int irq, void *dev_id, struct pt_regs *regs)//中断服务程序 { printk("\nin short_tl_interrupt!\n"); i++; } int short_init(void) //模块初始化 { int result; SET_MODULE_OWNER(&short_i_fops); /* Get our needed resources. */ result = check_region(base, SHORT_NR_PORTS); if (result) { printk(KERN_INFO "short: can't get I/O port address 0x%lx\n", base); return result; } request_region(base, SHORT_NR_PORTS, "short"); result = register_chrdev(major, "short", &short_i_fops); if (result < 0) { printk(KERN_INFO "short: can't get major number\n"); release_region(base,SHORT_NR_PORTS);//fail to get major release resource return result; } if (major == 0) major = result; /* dynamic */ short_base = ioremap(base, SHORT_NR_PORTS); short_irq=26; //固定中断号 if (short_irq >= 0) { result = request_irq(short_irq,short_tl_interrupt,SA_INTERRUPT,"test joystick", NULL); if (result) { printk(KERN_INFO "short-bh: can't get assigned irq %i\n", short_irq); short_irq = -1; } else { blr_mask_org=inw(short_base); outw(blr_mask_org|0x2000,short_base); } } if(short_irq>0) return 0;//success else return short_irq;//fail printk("%d\n",i); } void short_cleanup(void) { iounmap(short_base);//unmap release_region(base,SHORT_NR_PORTS);//release region if (short_irq >= 0) { outw(blr_mask_org,short_base); /* disable the interrupt */ free_irq(short_irq, NULL); } unregister_chrdev(major, "short"); printk("%d\n",i); } module_init(short_init); module_exit(short_cleanup); |
|
沙发#
发布于:2004-08-09 13:49
Are you sure you have entered you interrupt handler? I don't know what kind of hardware you have, but I think you have to clean the hardware interrupt status in you interrupt handler.
|
|
|
板凳#
发布于:2004-08-11 16:25
中断处理程序有问题
关掉中断之后是否在处理之后打开中断? |
|
地板#
发布于:2004-08-13 12:20
毛病在哪我没看出来,不过另一种事要注意,中断里面不要做printk,会出毛病的
|
|