linux中断机制及中断注册2(韦东山的视频总结及针对linux-2.6.30.4)

来源:互联网 发布:雅思阅读什么网络课好 编辑:程序博客网 时间:2024/04/28 21:23
自己的总结有错误请评论,我们共同进步
中断注册使用函数request_irq来注册,request_irq究竟做了什么,下面来分析:
 








注册外部中断1 触发方式是双边沿 为例
request_irq(IRQ_EINT1,buttons_irq,IRQ_TYPE_EDGE_BOTH,"s1",1);
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev)
{
return request_threaded_irq(IRQ_EINT1, buttons_irq, NULL, IRQ_TYPE_EDGE_BOTH,"s1", 1);
}

 

/**************request_threaded_irq(IRQ_EINT1buttons_irq, NULL, IRQ_TYPE_EDGE_BOTH,"s1"1)********/

request_threaded_irq(IRQ_EINT1,buttons_irq, NULL,IRQ_TYPE_EDGE_BOTH,"s1",1);
int request_threaded_irq(unsigned int irq, irq_handler_t handler,
irq_handler_t thread_fn, unsigned long irqflags,
const char *devname, void *dev_id)
{
struct irqaction *action;
struct irq_desc *desc;
int retval;


desc = irq_to_desc(IRQ_EINT1);//找到irq_desc 数组项

action = kzalloc(sizeof(struct irqaction), GFP_KERNEL);
if (!action)
return -ENOMEM;


action->handler = buttons_irq;
action->thread_fn = NULL;
action->flags =  IRQ_TYPE_EDGE_BOTH;
action->name = "s1";
action->dev_id = 1;
/*******************结果为*****************/
desc = irq_desc + IRQ_EINT1


struct irqaction {
irq_handler_t= buttons_irq;
unsigned long flags=IRQ_TYPE_EDGE_BOTH;
cpumask_t mask;
const char *name;
void *dev_id=1;
struct irqaction *next=NULL;
int irq=IRQ_EINT1;
struct proc_dir_entry *dir;
irq_handler_t thread_fn=NULL;
struct task_struct *thread;
unsigned long thread_flags;
};
/************************************************/
retval = __setup_irq(IRQ_EINT1, desc, action);
if (retval)
kfree(action);
return retval;

}



/************************************__setup_irq展开**************************/
/*
  * Internal function to register an irqaction - typically used to
* allocate special interrupts that are part of the architecture.
  */
retval = __setup_irq(IRQ_EINT1, desc, action);
static int
__setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new)
{
struct irqaction *old, **old_ptr;
const char *old_name = NULL;
unsigned long flags;
int shared = 0;
int ret;  
if (!shared) {                      //非共享的成立
irq_chip_set_defaults(desc->chip);//设置chip (底层硬件访问函数)
/* Setup the type (level, edge polarity) if configured: */
if (IRQ_TYPE_EDGE_BOTH & IRQF_TRIGGER_MASK) {        // /*IRQF_TRIGGER_MASK为中断触发方式,定义在Interrupt.h中*/  
ret = __irq_set_trigger(desc, IRQ_EINT1,IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING);

}


/*********__irq_set_trigger(desc, irq,new->flags & IRQF_TRIGGER_MASK)展开*******/
  __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
unsigned long flags)
__irq_set_trigger(desc, IRQ_EINT1,IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)
{
int ret;
struct irq_chip *chip = desc->chip;
/* caller masked out all except trigger mode flags */
ret = chip->set_type(irq, flags); //设置引脚
return ret=0;
}
/*结果:设置引脚*/

/*****************************************************************/


if (!(desc->status & IRQ_NOAUTOEN)) {
desc->depth = 0;
desc->status &= ~IRQ_DISABLED;
desc->chip->startup(IRQ_EINT1);//使能中断

}
return 0;
}
/****************************************************************************************/

原创粉丝点击