中断方式1:发生中断后,在中断处理函数内读中断状态寄存器得到中断源(是uart还是key还是其他),再经过switch(中断源)各个case调用到不同的处理函数
中断方式2:发生中断后,芯片自己判断中断源并跳转到我们预先给“中断源处理地址寄存器”设定的地址处运行。(S5PV210)
VIC:vector interrupt controller: 使用4个VIC来处理一共93个中断源 VIC[0-3]
- 向量中断控制器中硬件实现的向量表
1 2 3 4 5
| VIC0VECTORADDR0 ... VIC0VECTORADDR16 //key接到了16号中断,所以关心这个寄存器 ... VIC0VECTORADDR31
|
- 中断源的优先级寄存器
1 2 3 4 5
| VIC0VECPRIORITY0 ... VIC0VECPRIORITY16 //暂时不关心优先级 ... VIC0VECPRIORITY31
|
- 对控制器做开关
1 2
| VIC0INTENABLE VIC0INTENCLEAR
|
- 状态寄存器
1 2
| VIC0IRQSTATUS VIC0FIQSTATUS
|
- 中断处理函数地址寄存器
多个中断源(gpio,extern,uart,key…)控制器 –> VIC[0-4] -> 中断主控制器 –> CPU
1 2 3 4 5 6 7 8 9 10
| extern void asm_irq(void); void irq_init(void){ #if 0 unsigned int tmp; tmp = *((unsigned int *)asm_irq); pEXECEPTION_IRQ = tmp; #else pEXECEPTION_IRQ = (unsigned int)asm_irq; #endif }
|
1 2 3 4 5
| irq_handler: stmfd sp!,{r0-r3,lr} bl irq_c_handler ldmfd sp!,{r0-r3,lr} subs pc,lr,#4
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| void irq_c_handler(void){ myputs("irq_c_handler\n"); if(VIC0IRQSTATU|VIC1IRQSTATUS|VIC2IRQSTATUS|SVIC3IRQSTATUS){ } void (*handler)(void) = NULL; handler = (void (*)(void))VIC0ADDRESS; if(handler) handler(); } void key1_handler(void){ myputs("key1_handler\n"); set EXT_INT_2_PENDING[0] = 1; set VIC0ADDRESS = 0; }
void key_init(void) { set GPH2.CON[3:0] = 1111;
set EXT_INT_2_CON[2:0] = 0b010; set EXT_INT_2_MASK[0] = 0b0;
set VIC0INTENABLE[16] = 1; VIC0VECTORADDR16 = key1_handler; }
int main(void) { irq_init(); key_init(); while(1); return 0; }
|