由于项目可能要采取lpc21XX系列芯片(arm7),这两天看了下lpc2104的datasheet,想起以前玩过arm9(s3c2410)的实验板,发现两者的中断处理有一定不同的地方,下面简略说明,如有不对之处,还请指正!
申明:由于FIQ(快速中断)在实际使用中较少用到,而且在不同平台下处理方式也类似,下面仅对IRQ进行说明。
1.lpc2104(ARM7内核)
其IRQ中断有向量中断和非向量中断之分
对于向量IRQ,需要设置两个内容,分别为VICVectCntlX(0-15)和VICVectAddrX(X:0-15),在VICVectCntlX中设置对应的中断源号,在VICVectAddrX中设置中断处理程序的入口地址,优先级依次递减,当产生向量IRQ时系统会自动跳转到VICVectAddrX处,处理完后需对VICVectAddr做清零操作;
而对于非向量IRQ,只需填写VICDefVectAddr的内容,当产生非向量IRQ时系统会自动跳转到VICDefVectAddr处,此时需读VICIRQStatus的值,做相应处理,处理完后需对VICVectAddr做清零操作;
2.s3c2410(ARM9内核)
其IRQ相对较简单,不存在向量中断和非向量中断之分,当产生中断时,通过INTOFFSET寄存器即可判断是什么中断,但其中断优先级可变,具体可以参考相应datasheet。
关于关键字"__irq":其实只是编译器在遇到该关键字时会增加现场保存与恢复工作的代码(根据编译器不同,可能有所不同),其中比较重要的一点是将LR恢复到PC中,实现中断程序的返回,所以如果程序已用汇编代码保存恢复现场,并在最后已将LR恢复到PC中,则c处理函数中不需加"__irq",如用lpc2000模版生成的程序,否则应该加该关键字。
关于中断处理程序中的"写1清0":处理程序中用"|="和"="是有很大差别的,如T0IR = 0x01是将最低标志位清0,而T0IR |= 0x01是将T0IR中所有是1的位和最低位都清零,因为T0IR |= 0x01,是将T0IR和0x01相或后再回写,这一点可以在反汇编代码中看出,当然不同的编译器可能有所不同。