第一:中断的基本简介
中断系统是一个处理器重要的组成部分,中断系统极大的提高了CPU的中断执行效率。芯片本身也有中断向量表,中断向量表也是在代码的最前面。A7内核有8个异常中断,这8个异常中断的中断向量表如图:
中断向量表中都是中断服务函数的入口地址,因此芯片有什么中断都是可以从中断向量表中看出来的。难道A7系列只有7个中断吗?显然是不可能的。A内核的CPU所有的外部中断都属于这个IRQ中断,当任意一个外部中断发生的时候都触发这个IRQ中断。在IRQ中断服务函数里面就可以读取指定的寄存器来判断发生的具体是什么中断,进而根据具体的中断做出相应的处理。
在左侧都是Software0_IRQn~PMU_IRQ2_IRQ都是外设IRQ中断,中断任意一个发生的时候IRQ中断都会被触发,需要在IRQ中断服务函数中判断究竟是哪个中断发生了,然后再做出具体的处理。
常用的复位中断和IRQ中断,需要编写这两个中断的中断服务函数,稍后会讲解如何编写对应的中断服务函数。首先要来编写中断向量表:
.global _start _start: ldr pc, =Reset_Handler /* 复位中断 ldr pc, =Undefined_Handler /* 未定义指令中断 */ ldr pc, =SVC_Handler /* SVC(Supervisor)中断 */ ldr pc, =PrefAbort_Handler /* 预取终止中断 */ ldr pc, =DataAbort_Handler /* 数据终止中断 */ ldr pc, =NotUsed_Handler /* 未使用中断 */ ldr pc, =IRQ_Handler /* IRQ 中断 */ ldr pc, =FIQ_Handler /* FIQ(快速中断)未定义中断 */ /* 复位中断 */ Reset_Handler: /* 复位中断具体处理过程 */ /* 未定义中断 */ Undefined_Handler: ldr r0, =Undefined_Handler bx r0 /* SVC 中断 */ SVC_Handler: ldr r0, =SVC_Handler bx r0 /* 预取终止中断 */ PrefAbort_Handler: ldr r0, =PrefAbort_Handler bx r0 /* 数据终止中断 */ DataAbort_Handler: ldr r0, =DataAbort_Handler bx r0 /* 未使用的中断 */ NotUsed_Handler: ldr r0, =NotUsed_Handler bx r0 /* IRQ 中断!重点!!!!! */ IRQ_Handler: /* 复位中断具体处理过程 */ /* FIQ 中断 */ FIQ_Handler: ldr r0, =FIQ_Handler bx r0
中断服务函数都是用汇编编写的,我们实际需要 编写的只有复位中断服务函数 Reset_Handler 和 IRQ 中断服务函数 IRQ_Handler,其它的中断没有用到,所以都是死循环。
第二:GIC控制器介绍
GIC是ARM公司给Cortex-A内核提供的一个中断控制器,类似Cortex-M内核中的NVIC。目前有4个版本:V1~V4,V1是最老的版本,已经废弃。GIC V2 是给 ARMv7-A 架构使用的,比如 Cortex-A7、Cortex-A9、Cortex-A15 等, V3 和 V4 是给 ARMv8-A/R 架构使用的,也就是 64 位芯片使用的。GIC V2 最多支持 8 个核。ARM 会根据 GIC 版本的不同研发 出不同的 IP 核,那些半导体厂商直接购买对应的 IP 核即可,比如 ARM 针对 GIC V2 就开发出 了 GIC400 这个中断控制器 IP 核。当 GIC 接收到外部中断信号以后就会报给 ARM 内核,但是 ARM 内核只提供了四个信号给 GIC 来汇报中断情况:VFIQ、VIRQ、FIQ和IRQ,他们之间关系如图。
GIC接收众多的外部中断,然后对其处理,最终就只通过四个信号报给ARM内核,这四个信号的含义如下:
VFIQ:虚拟快速 FIQ。 VIRQ:虚拟外部 IRQ。 FIQ:快速中断 IRQ。 IRQ:外部中断 IRQ。 VFIQ 和 VIRQ 是针对虚拟化的,我们不讨论虚拟化,剩下的就是 FIQ 和 IRQ 了。
GIC将众多的中断源分为三类:
①、SPI(Shared Peripheral Interrupt),共享中断,顾名思义,所有 Core 共享的中断,这个是最 常见的,那些外部中断都属于 SPI 中断(注意!不是 SPI 总线那个中断) 。比如按键中断、串口 中断等等,这些中断所有的 Core 都可以处理,不限定特定 Core。
②、PPI(Private Peripheral Interrupt),私有中断,我们说了 GIC 是支持多核的,每个核肯定 有自己独有的中断。这些独有的中断肯定是要指定的核心处理,因此这些中断就叫做私有中断。
③、SGI(Software-generated Interrupt),软件中断,由软件触发引起的中断,通过向寄存器 GICD_SGIR 写入数据来触发,系统会使用 SGI 中断来完成多核之间的通信。
总结:高端芯片中断系统非常复杂,分析到这里还有很多细节没有分析,等到下回分解,感兴趣的可以研究一下。中断系统对后面灵活使用嵌套功能非常有用。