GIC架构简介
GIC是中断管理控制器,类似STM32的NVIC
GIC负责收集中断源并发送给CPU
中断源--->GIC--->CPU
问题一:中断源有哪些?
中断源分为三种:
SPI:共享中断(如串口中断,定时器中断等)
PPI:私有中断
SGI:软件中断
为了区分这些中断源引入中断ID
I.MX6U 的总共使用了 128 +32个中断 ID
ID0~ID15:这 16 个 ID 分配给 SGI。
ID16~ID31:这 16 个 ID 分配给 PPI。
ID32~ID1019:这 988 个 ID 分配给 SPI,像 GPIO 中断、串口中断等这些外部中断 。、
问题二:GIC怎么告诉CPU
GIC 接收众多的外部中断,然后对其进行处理,最终就只通过四个信号报给 ARM 内核,这四个信号的含义如下:
VFIQ:虚拟快速 FIQ。
VIRQ:虚拟快速 IRQ。
FIQ:快速中断 IRQ。
IRQ:外部中断 IRQ。
我们主要关心IRQ
问题三:GIC对中断源都进行什么操作
GIC 架构分为了两个逻辑块:Distributor 和 CPU Interface,也就是分发器端和 CPU 接口端。这两个逻辑块的功能如下:
Distributor( 分发器端) :此逻辑块负责处理各个中断事件的分发问题,也就是中断事件应该发送到哪个 CPU Interface 上去。分发器收集所有的中断源,可以控制每个中断的优先级,它总是将优先级最高的中断事件发送到 CPU 接口端。分发器端要做的主要
工作如下:
①、全局中断使能控制。
②、控制每一个中断的使能或者关闭。
③、设置每个中断的优先级。
④、设置每个中断的目标处理器列表。
⑤、设置每个外部中断的触发模式:电平触发或边沿触发。
⑥、设置每个中断属于组 0 还是组 1。
CPU Interface(CPU 接口端):CPU 接口端听名字就知道是和 CPU Core 相连接的,因此每个 CPU Core 都可以在 GIC 中找到一个与之对应的 CPU Interface。CPU 接口端就是分发器和 CPU Core 之间的桥梁,CPU 接口端主要工作如下:
①、使能或者关闭发送到 CPU Core 的中断请求信号。、
②、应答中断。
③、通知中断处理完成。
④、设置优先级掩码,通过掩码来设置哪些中断不需要上报给 CPU Core。
⑤、定义抢占策略。
⑥、当多个中断到来的时候,选择优先级最高的中断通知给 CPU Core。
问题四,如何操作GIC寄存器?
首先要知道GIC寄存器的地址
GIC寄存器的基地址保存在CP15协处理器的CBAR寄存器中,使用一下命令来获取GIC基地址
MRC p15, 4, r1, c15, c0, 0 ; 获取 GIC 基础地址,基地址保存在 r1 中。
CPU接口端基地址为GIC基地址+0x2000偏移地址
ADD r1, r1, #0X2000 ;GIC 基地址加 0X2000 得到 CPU 接口端寄存器起始地址
GICC_IAR寄存器保存中断ID,其地址为CPU接口端地址+0XC偏移地址
LDR r0, [r1, #0XC] ;读取 CPU 接口端起始地址+0XC 处的寄存器值,也就是寄存器;GIC_IAR 的值
问题五:GIC中如何控制中断使能?
使能中断首先要开启IRQ总开关。
如何开启IRQ中断使能
cpsid i 禁止 IRQ 中断。
cpsie i 使能 IRQ 中断。
然后开启各个外部中断开关。
如何使能串口中断,定时器中断,也就是说如何使能128个外部中断
GIC 寄存器 GICD_ISENABLERn 和 GICD_ ICENABLERn 用来完成外部中断的使能和禁止,对于 Cortex-A7 内核来说中断 ID 只使用了 512 个。一个 bit 控制一个中断 ID 的使能,那么就需要 512/32=16 个 GICD_ISENABLER 寄存器来完成中断的使能。同理,也需要 16 个GICD_ICENABLER 寄存器来完成中断的禁止。其中 GICD_ISENABLER0 的 bit[15:0]对应
ID15~0 的 SGI 中断,GICD_ISENABLER0 的 bit[31:16]对应 ID31~16 的 PPI 中断。
剩下的GICD_ISENABLER1~GICD_ISENABLER15 就是控制 SPI 中断的。
问题六:如何设置中断优先级?
GICC_PMR 寄存器只有低 8 位有效,这 8 位最多可以设置 256 个优先级。
11111111 256 个优先级
11111110 128 个优先级
11111100 64 个优先级
11111000 32 个优先级
11110000 16 个优先级
I.MX6U 最多支持 32 个优先级,所以 GICC_PMR 要设置为 0b11111000。
设置抢占优先级和子优先级。
GICC_BPR寄存器决定抢占优先级和子优先级的比例,寄存器GICC_BPR只有低3位有效。
000 :7 级抢占优先级,1 级子优先级。
001:6 级抢占优先级,2 级子优先级。
010:5 级抢占优先级,3 级子优先级。
011:4 级抢占优先级,4 级子优先级。
100:3 级抢占优先级,5 级子优先级。
101:2 级抢占优先级,6 级子优先级。
110:1 级抢占优先级,7 级子优先级。
111: 0 级抢占优先级,8 级子优先级。
I.MX6U 的优先级位数为 5(32 个优先级),所以可以设置 Binary point 为 2,表示 5 个优先级位全部为抢占优先级。
每个中断ID优先级配置
I.MX6U 一共有 32 个抢占优先级,数字越小优先级越高。具体要使用某个中断的时候就可以设置其优先级为 0~31。某个中断 ID 的中断优先级设置由寄存器D_IPRIORITYR 来完成。
每个中断 ID 配有一个优先级寄存器,使用寄存器 D_IPRIORITYR 的 bit7:4 来设置优先级
比如要设置ID40 中断的优先级为 5,示例代码如下:
GICD_IPRIORITYR[40] = 5 << 3;
https://blog.csdn.net/qq_35947329/article/details/103101594?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522161165275416780264075572%252522%25252C%252522scm%252522%25253A%25252220140713.130102334.pc%25255Fall.%252522%25257D&request_id=161165275416780264075572&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v29-3-103101594.pc_search_result_cache&utm_term=IMX%20GIC
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。