|
我写了一个小程序,用来测试中断的加载和调用,程序及问题如下,请路过高手指点迷津
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/module.h>
#define pad_irq 33
static void pad_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
printk("key pressed\n");
printk("interrupte num is %i\n", irq);
}
int pad_init(void)
{
free_irq(pad_irq, NULL);
if ( request_irq(pad_irq, pad_interrupt,SA_INTERRUPT, "pad", NULL) )
printk("can't get assigned irq %i\n ",pad_irq);
}
void pad_cleanup(void)
{ }
init_module(void) {
printk("pad driver installed!\n");
pad_init();
printk("requested irq\n");
}
cleanup_module(void) {
free_irq(pad_irq, NULL);
printk("pad driver removed!\n");
}
编译通过以后我加载如下
# insmod pad_irq1.o
出现如下信息
Using pad_irq1.o
Insmod: init_module: pad_irq1: Device or resource busy
不知道问题出在什么地方,中断号肯定是唯一的,也查了一下中断是没有被占用的,我看到有个
函数返回的是-EBUSY
具体函数如下
int setup_irq(unsigned int irq, struct irqaction * new)
{
int shared = 0;
unsigned long flags;
struct irqaction *old, **p;
irq_desc_t *desc = irq_desc + irq;
/*
* Some drivers like serial.c use request_irq() heavily,
* so we have to be careful not to interfere with a
* running system.
*/
if (new->flags & SA_SAMPLE_RANDOM) {
/*
* This function might sleep, we want to call it first,
* outside of the atomic block.
* Yes, this might clear the entropy pool if the wrong
* driver is attempted to be loaded, without actually
* installing a new handler, but is this really a problem,
* only the sysadmin is able to do this.
*/
rand_initialize_irq(irq);
}
/*
* The following block of code has to be executed atomically
*/
[1] spin_lock_irqsave(&desc->lock,flags);
p = &desc->action;
if ((old = *p) != NULL) {
/* Can't share interrupts unless both agree to */
if (!(old->flags & new->flags & SA_SHIRQ)) {
[2] spin_unlock_irqrestore(&desc->lock,flags);
return -EBUSY;
}
/* add new interrupt at end of irq queue */
do {
p = &old->next;
old = *p;
} while (old);
shared = 1;
}
*p = new;
if (!shared) {
desc->depth = 0;
desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT |IRQ_WAITING);
desc->handler->startup(irq);
}
[3] spin_unlock_irqrestore(&desc->lock,flags);
register_irq_proc(irq);
return 0;
} |
|