中断基本概念
- 中断管理
- 2023-03-04
- 90热度
- 0评论
在现代嵌入式系统中,处理器上会挂接很多个外设,CPU在执行任务的时候,可能会同时由多个中断发生,那么中断必要要进行响应处理并维护一个队列一一运行,这样自然会影响CPU的效率,为了让CPU专注于实际运算,中断控制器孕育而生,各中断信号源都先交给中断控制器处理,由中断控制器进行管理,同时接受多个中断请求并进行优先级判断,然后选中一个最高优先级的请求送个CPU进行处理,在CPU响应处理中断时,中断控制器仍然可以响应外部中期的请求,在多核系统中,中断控制器还可以承担路由的作用,将某些中断送到指定CPU进行处理,以达到中断处理的负载均衡。在X86架构中断控制器称为APIC(Advanced Programmable Interrupt Controller),ARM架构的中断控制器则称为GIC(Generic Interrupt Controller),本文主要探讨的是GIC模块。
ARM架构的GIC目前已经发展了多个版本,不同的GIC IP使用于不同的ARM架构,下面是不同版本直接的关键features。
Version | Key features | Architecture | Tpically used with |
---|---|---|---|
GICv1 | Support for up to eight PEs.Support for up to 1020 interrupt IDs.Support for two Security states. | A5/A9/R7 | |
GICv2 | All key features of GICv1.Support for virtualization. | GIC400 | A7/A15/A53/A57 |
GICv3 | All key features of GICv2.Support for more than eight PEs.Support for message-based interrupts.Support for more than 1020 interrupt IDs.System register access to the CPU Interface registers.An enhanced security model, separating Secure and Non-secure Group 1 interrupts. | GIC500 | A72/A53/A57 |
GICv4 | All key features of GICv3 and.Direct injection of virtual interrupts | GIC600 | A53/A57/A72 |
GICv2架构
GICv2将中断源类型进行分类。
类型 | 中断号范围 | 说明 |
---|---|---|
SGI | ID0~ID15 | Software Generated Interrupt,软件触发中断,通常用于多核之间通信。 |
PPI | ID16~ID31 | Pivate Peripheral Interrupt,每个处理核私有中断,如timer,hw fault等。 |
SPI | ID32~ID1019 | Shared Peripheral Interrupt,公用外设中断,最多支持998个。 |
中断源类型的划分是输入给GIC的角度进行的,而GIC输出到CPU只有IRQ(Interrupt Request)和FIQ(Fast Interupt Request),FIQ主要用于安全OS,不适用于Linux内核本文也暂不讨论。
GIC在GICv2中,有两大模块组成,distributor和interface。
- Distributor:实现中断的分发,从上图可以看出,SPIs Interrupt ID 32~1019中断是共享的,将会根据事先配置的寄存器GICD_xxx选择最高优先级的中断发往CPU核,PPI、SGI是各CPU独有的中断,不参与目的core的仲裁。distributor对中断主要提供全局中断使能、每个中断使能、中断优先级、中断分组、中断目的CPU核、中断触发方式、中断状态管理、可修改中断的Pending状态等。
- Interface:将GICD发送的中断信息,通过IRQ/FIQ传输给CPU核。这里分为CPU interface和Virtual CPU interface,后者暂未接触先不讨论。interface提供将中断请求发送给CPU、CPU对中断进行确认、中断处理通知完成、设置中断优先级屏蔽等。
GICv3架构
类型 | 中断号范围 | 说明 |
---|---|---|
SIGs | ID0~ID15 | Software Generated Interrupt,软件触发中断,通常用于多核之间通信。 |
PPIs | ID16~ID31 | Pivate Peripheral Interrupt,每个处理核私有中断,如timer,hw fault等。 |
SPIs | ID32~ID1019 | Shared Peripheral Interrupt,公用外设中断,最多支持998个。 |
ID1020~ID1023 | Used to signal special cases | |
1024~8191 | Reserved | |
LIPs | 8192~ | Locality-specific Peripheral Interrupt,外设不通过专用中断线向GIC发中断,而是基于消息的中断,配置信息存储在memmory中,通过ITS可以解析消息发送给Redistributor触发中断。 |
相对于GICv2架构GICv3多一个模块,Resdistributor。
- Distributor:主要用来管理配置SPIs类型的中断。
- Resdistributor:每个PE(process element,即cpu核)都对应一个,所以想要的配置是针对某个CPU核的,主要用来配置SGI和PPI类型中断。
- CPU Interface:每个PE对应一个interface,与GICv2的interface一致。
引入LPIs后,对于中断源触发信号给中断控制器就可以分为两类,peripheral interrupt signal和Peripheral interrupt message。
在GICv3,SPIs类型也是可以配置成message 类型中断,但是LPIs只能是message类型中断。
GIC V3版本中寄存器如上图所示,提供了两种方式访问,memory-mapped和系统寄存器访问。
寄存器 | 说明(memory-mapped访问方式) |
---|---|
GICC | CPU interface寄存器 |
GICD | Distributor寄存器 |
GICR | Redistributor寄存器 |
寄存器 | 说明(系统寄存器方式方式) |
---|---|
ICC | 物理 CPU interface系统寄存器 |
中断处理过程
状态机
上图是中断控制器的状态机,四种状态适用于SPI,PPI和SGI类型的中断源,而LPIs没有active或active and pending状态。
- Inactive:中断源没有触发信号。
- Pending:中断源触发了信号,GIC会将IAR(Interrupt Acklowlege Register)中该中断源对应bit置1,然后通知了CPU,但CPU没有响应ACK给GIC。
- Active:CPU读取了IAR寄存器置1的位,CPU通过interface读取IAR的寄存器表示确认了这个中断并开始处理,此时中断源进入Active状态。
- Active and Pending:CPU ACK了这个中断请求后,中断控制器就解除了对该中断源的屏蔽,控制器可以继续响应中断,那么当CPU还在处理中断服务器程序时,此时中断源又触发了信号给中断控制器,此时的状态就处于Acitive and Pending,简称AP。
当CPU完成了中断程序处理,就会写中断控制器的EOI(End of Interrupt)寄存器,中断源的状态就会再次回到inactive状态。
CPU在处理中断程序期间是屏蔽掉IRQ的响应的,处理完成之后才会打开中断响应。这里要注意的是CPU的中断屏蔽和中断控制器的屏蔽是两回事,CPU屏蔽的是IRQ而中断控制器屏蔽的是SPIs/PPIs/SGIs/LPIs。
触发方式
电平触发
电平触发方式时序图如上,可以分为以下几个阶段变化:
- Inactive to Pending:中断源触发了信号给到中断控制器,GIC收到信号后,如果CPU使能了该中断则触发信号给PE。上图Peripheral To GIC的信号被拉高,继而触发GIC To Core的信号被拉高。
- Pending to AP:PE通过CPU interface读取了IARs寄存器,状态转为Active。由于CPU操作的是中断控制器,但并没有对设备进行处理,所以设备给中断控制器的触发信号高电平会一直维持,因此会再次触发中断控制器对应bit置位,表示中断又来了。
- AP to Active:对应高电平的触发类型,通常需要CPU收到中断信号后再去响应外设,如写外设相关寄存器或读写外设的数据等,外设的中断源才会取消触发(高电平->低电平)。状态再次从AP转到Active。
- Active to Inactive:CPU处理完了中断响应程序,然后写中断控制器EOIRs寄存器,表示中断处理完成。
边沿触发
- Inactive to Pending:中断源触发了信号给到中断控制器,GIC收到信号后,如果CPU使能了该中断则触发信号给PE,在CPU没有ACK之前,GIC to Core的电平会被一直拉高,直到CPU做出ACK动作。
- Pending to Active:与电平触发类似。
- Active to A&P:Linux在处理中断过程中是不允许中断嵌套的,但此时如果有外设再次触发中断,但也不影响,因为中断控制器可以进行处理相当于锁存主第二个中断的到来,这样第二个中断也不会丢失。
- A&P to Pending:边沿触发方式通常不需要CPU对外设进行中断信号清除,当cpu处理完了当前中断后,会转入准备处理第二个中断。
- 边沿触发有丢中断的可能,一般情况下可靠性高的使用电平触发方式。
中断控制器的pengding位,在软件处理完成写eoi寄存器后硬件自己会清除,所以软件不需要清pending,但是对于外设是电平类型触发来说,需要清除外设的电平触发源(操作的不是中断控制器,是外设)。