一:了解中断流程
单片机的中断流程是:
在/work/system/linux-2.6.22.6下vim ./config_ok,知道内核的异常向量地址为0xffff0000
有关于内核的中断机制,查看《嵌入式Linux应用开发完全手册》的p411
那linux的中断流程是怎么样
1.用trap_int构造异常向量,异常向量是:
2.把代码拷贝到0xffff0000去
3.然后调用irq_handler(在arch/arm/kernel的entry-armv.S调用),然后调用asm_do_IRQ这个c函数,这个就是处理函数
4.调用完毕后恢复
5.总结:和单片机没太大区别
a.按下按键
b.进入异常模式
c.asm_do_IRQ
二.了解内核中断处理流程
上面说到调用处理函数asm_do_IRQ这个c函数,那中断处理过程是怎样的
1.对应单片机
2.对与linux,上面的三项都是在asm_do_IRQ函数中实现的
asm_do_IRQ函数里进入desc_handle_irq(irq, desc);处理函数
搜索desc->handle_irq(irq, desc);,发现这个函数是被__set_irq_handler调用,里面使用了中断描述结构体
中断入口函数handle_irq做的事:有清中断、处理中断(取出action链表里的成员,执行对应action->handler)
__set_irq_handler被set_irq_handler调用,继续搜索可以知道,最终调用action->handler();这个中断处理函数。
因此我们自己写的驱动代码就是在action->handler()里。内核提供给我们request_irq()这个函数来告诉内核我们的处理函数。
request_irq()分析:
-
分配irqaction结构体
-
调用setup_irq(irq, action);(设置中断)
1.找到struct irq_desc *desc = irq_desc + irq;把结构体irqaction放入irq_desc[irq]里的action链表
2.判断链表头
3.设置中断引脚desc->chip->settype()
4.使能中断desc->chip->startup/enable
request_irq()是注册中断服务程序,而free_irq是卸载中断服务程序(中断,禁止中断)
void free_irq(unsigned int irq, void *dev_id)
下一节具体实现怎么用request_irq()和free_irq实现按键驱动