linux中斷機制及中斷註冊2(韋東山的視頻總結及針對linux-2.6.30.4)

自己的總結有錯誤請評論,我們共同進步
中斷註冊使用函數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;
}
/****************************************************************************************/

發佈了36 篇原創文章 · 獲贊 7 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章