一、中断相关结构体
1.irq_desc中断描述符
2.irq_chip 芯片相关的处理函数集合
3.irqaction中断行动结构体
在整个中断系统中将勾勒出以下的关系框图
二、中断初始化工作
从start_kernel看起,大致按以下的分支顺序初始化
1.在setup_arch中主要是设置全局init_arch_irq函数
1.1.early_trap_init主要挪移了中断向量表到特定位置
2.early_irq_init 初始化全局irq_desc数组
在(kernel/irqs/irqdesc.c)中定义了全局irq_desc数组
获取irq_desc数组项的宏
early_irq_init函数
3.init_IRQ函数调用全局init_arch_irq函数,进入板级初始化
4.板级中断初始化常用到的API
1.set_irq_chip 通过irq中断号获取对应全局irq_desc数组项,并设置其irq_data.chip指向传递进去的irq_chip指针
1.1 irq_chip_set_defaults 根据irq_chip的实际情况初始化默认方法
2.set_irq_handler和set_irq_chained_handler
这两个函数的功能是:根据irq中断号,获取对应全局irq_desc数组项,并将数组项描述符的handle_irq中断处理函数指针指向handle
如果是chain类型则添加数组项的status状态IRQ_NOREQUEST和IRQ_NOPROBE属性
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2.1 __set_irq_handler函数
3.set_irq_flags 根据irq号获取全局irq_desc数组项,并设置其status标志(中断标志)
4.set_irq_type根据irq号获取全局irq_desc数组项,并设置其status标志(中断触发类型)
4.1 __irq_set_trigger函数
5.set_irq_chip_data 根据irq号获取全局irq_desc数组项,并设置其irq_data的chip_data
6.set_irq_data
三、中断的申请与释放request_irq
1.申请中断(主要是分配设置irqaction结构体)
1.1 request_threaded_irq函数
1.2 __setup_irq函数
代码可以去细究,主要功能是填充irqaction
在设备驱动程序中申请中断可以这么申请
(eg:request_irq(1, &XXX_interrupt,IRQF_TRIGGER_RISING,"nameXXX", (void*)0))
第一个参数是中断号,第二个参数是中断处理函数,第三个参数是中断标志(上升沿),第四个是名字,第五个是设备id(非共享中断设置成(void*)0)即可
共享中断情况下要将第三个参数添加IRQF_SHARED标志,同时要给他制定第五个参数设备id
触发方式宏
然后设计中断函数
static irqreturn_t XXX_interrupt(int irq, void *arg){
……
return IRQ_HANDLED;
}
2.释放中断
2.1 __free_irq
四、中断处理过程
1.当有中断发生时,程序会到__vectors_star去查找向量表(arch/arm/kernel/entry-armv.S)
2.vector_irq的定义声明
3.vector_stub宏的定义
这几段汇编的大致意思是中断发生会跳到vector_irq去执行,vector_irq根据情况会跳到__irq_usr或__irq_svc执行
4.__irq_usr
5.__irq_svc
6.不管是__irq_svc或是__irq_usr都会调用到irqhandler
7.就这样进入了c处理的阶段asm_do_IRQ
8.generic_handle_irq函数
9.generic_handle_irq_desc函数
这里有了分支关键看CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ的设置
如果设置为1,则只调用中断描述符的handle_irq方法
如果设置为0,则如果中断描述符存在handle_irq方法则调用该方法,如果没有则调用__do_IRQ()
中断描述符handle_irq方法,一般是芯片厂商写好的,先看看__do_IRQ()吧
10.__do_IRQ函数
.__do_IRQ函数主要是调用handle_IRQ_event来处理中断
11.handle_IRQ_event函数
这里调用的irqaction的handler方法就是调用了之前设备驱动中用request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,const char *name, void *dev)
申请中断时传递进来的第二个参数的函数
其实很多芯片厂商在编写中断描述符handle_irq方法的时候也会调用到handle_IRQ_event函数
整个中断的处理过程就是
手机扫一扫
移动阅读更方便
你可能感兴趣的文章