中断系统流程解析:
asm_do_IRQ(unsigned int irq, struct pt_regs *regs)
handle_IRQ(irq, regs);
generic_handle_irq(irq);/*进行一般的中断处理*/
struct irq_desc *desc = irq_to_desc(irq); /*#define irq_to_desc(irq) (&irq_desc[irq]) /* 他是以irq为下标的一个全局数组项*/
generic_handle_irq_desc(irq, desc);
desc->handle_irq(irq, desc); /* 那么究竟是谁调用handle_irq ??? 下面进行分析*/
// 问:所以是谁调用handle_irq ?
// 答:进行搜索handle_irq然后进入kernel\irq\Chip.c
__irq_set_handler(unsigned int irq, irq_flow_handler_t handle, int is_chained,
struct irq_desc *desc = irq_get_desc_buslock(irq, &flags, 0);/*Garmen : 以irq为索引,找到一项*/
desc->handle_irq = handle; /* 这里进行设置,把上面以irq为索引找到的那项的handle_irq指定为传进来的参数handle*/
// 然后我们再搜索__irq_set_handler被谁调用:
irq_set_handler(unsigned int irq, irq_flow_handler_t handle)
__irq_set_handler(irq, handle, 0, NULL);
// 而且我们在linux-3.4.2\arch\arm\plat-s3c24xx\Irq.c 发现:
void __init s3c24xx_init_irq(void) /* : 其实下面这些就相当于初始化函数*/
for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++)
irq_set_chip_and_handler(irqno, &s3c_irq_eint0t4,handle_edge_irq); /* 再跟进去*/
/*irqno对应的就是上面irq_desc的irq索引
*然后你会惊人的发现这个handle_edge_irq 就是handle就是上面desc->handle_irq = handle 中断处理函数
*/
irq_set_chip_and_handler_name(irq, chip,handle, NULL);
irq_set_chip(irq, chip);
desc->irq_data.chip = chip; /* chip函数也是一样,有跟进来的irq索引和chip*/
__irq_set_handler(irq, handle, 0, name); /* 于是我们惊人的发现这个函数被调用了*/
再研究一下handle_edge_irq
handle_edge_irq:
/* Start handling the irq */
desc->irq_data.chip->irq_ack(&desc->irq_data);
handle_irq_event(desc);
struct irqaction *action = desc->action; /* 取出desc中action成员*/
ret = handle_irq_event_percpu(desc, action); /* 执行action相关函数*/
小结:问:按下按键之后怎么处理
答:
1、进入异常模式:b vector_irq + 偏移值
2、调用列表,比如调用到irq_usr,保持现场什么的工作
3、调用asm_do_irq
4、调用irq_desc[irq]->handle_irq /* 以中断号为下标,取出一项处理函数*/
5、上面的handle_irq 就是一个中断处理函数 , 好比如handle_edge_irq
里面做了什么事情呢?参考上面
handle_edge_irq的研究
irq_desc结构体定义及其说明:
他是一个全局数组
①:
chip是一些芯片底层硬件相关的操作(比如响应中断、清中断等等),在linux3.4.2内核。他在irq_data这个数组里面,这里没有列出来
②:
handle_irq是中断处理函数,将acit