Linux内核中断处理流程

来源:互联网 发布:网络电视可以看直播吗 编辑:程序博客网 时间:2024/05/17 17:16

中断的处理流程

1

.发生中断的时候,CPU执行异常向量的代码,如下:

__vectors_start:

         swi   SYS_ERROR0

         b       vector_und + stubs_offset

         ldr    pc, .LCvswi + stubs_offset

         b       vector_pabt + stubs_offset

         b       vector_dabt + stubs_offset

         b       vector_addrexcptn + stubs_offset

         b       vector_irq + stubs_offset

         b       vector_fiq + stubs_offset

 

         .globl        __vectors_end

__vectors_end:

2.在执行上面地址的代码的时候,最终会调用中断处理的总入口函数asm_do_IRQ,在执行asm_do_IRQ之前一直是跑汇编代码的,asm_do_IRQ的第一个参数irq的取值范围为(IRQ_EINT0~IRQ_ENINT0+31))只有32个取值,这个值是根据INTOFFSET寄存器的每个位得到的。

3asm_do_IRQ根据中断号调用irq_desc数组项中的handle_irq

4.handle_irq会使用chip成员中的函数来设置硬件,比如清除中断,禁止中断,重新使能中断等。

5Handle_irq逐个调用用户在action链表中注册的处理函数

(a)  Irq_desc结构数组,他的成员“struct irq_chip * chip,struct irqaction * action”这三种数据结构构成了中断处理体系的框架。

 

 

中断处理体系结构的初始化

1.  Init_IRQ函数初始化中断处理体系

{

           Init_arch_irq();

}

Init_arch_irq()函数执行的实体在开发板初始化的时候就给了。在mach-smdk2440.c

 

 

在驱动中中断的使用过程

1.  通过request_irq 函数向内核注册中断处理函数,处理如下:

int request_irq(unsigned int irq, irq_handler_t handler,

   unsigned long irqflags, const char *devname, void *dev_id)

{      

action->handler = handler;

action->flags = irqflags;

cpus_clear(action->mask);

action->name = devname;

action->next = NULL;

    action->dev_id = dev_id;

//构造一个irqaction结构

Retval  =  Setup_irq(irq,action);

//调用setup_irq函数讲它链入链表中

}

2.  Setup_irq函数完成以下功能

(1)       将新建的irqaction结构链入irq_desc[irq]结构的action链表中

(a)       如果这个链表是空的,直接链入

(b)       否则先判断新建的irqaction结构和链表中的irqaction结构所表示的中断类型是否一致:即是否都声明为“可共享的”,是否都使用相同的触发方式(电平,边沿,极性),如果一致将新建的irqaction结构链入。

(2)       设置irq_desc[irq]结构中chip成员的还没设置的指针,让它们指向一些默认函数

这个通过irq_chip_set_defaults(desc->chip);实现

(3)       设置中断的触发方式

利用request_irq传入的参数irqflags来设置中断触发方式(高电平出发,低电平触发,上升沿触发,下降沿触发)

(4)       启动中断

chip->startup chip->enable 来启动中断的

     小结使用request_irq函数之后的“成果”

(1)       Irq_desc[irq]结构中的action链表中已经链入了用户注册的中断处理函数

(2)       中断的触发方式已经设置好

(3)       中断已经被使能了

总之,执行完request_irq函数之后,中断就可以发生并能够被处理了。

 

转自:http://blog.mcuol.com/User/longren/Article/12931_1.htm

原创粉丝点击