1、说明
\qquad
本文叙述了ZYNQ芯片中断相关内容,并且例举了PL-PS中断实例。参考文献ug585.
2、系统中断架构
\qquad
每个CPU都有一组私有外围中断(PPIs),通过使用banked register进行私有访问。PPIs包括全局定时器、私有看门狗定时器、私有定时器和来自PL的FIQ/IRQ。
\qquad
软件产生的中断(SGIs)被路由到一个或两个cpu。SGIs是通过写入通用中断控制器(GIC)中的寄存器来生成的。
\qquad
共享外围中断(SPI)由PS和PL中的各种I/O和内存控制器生成。它们被路由到其中一个或两个cpu。来自PS外围设备的SPI中断也被路由到PL。
3. 通用中断控制器(GIC)
\qquad
通用中断控制器(GIC)用于管理来自PS和PL的发送到CPU的中断。当CPU接口接收到下一个中断时,控制器启用、禁用、屏蔽、对中断源进行优先排序,然后以编程的方式将它们发送到所选的CPU(或CPU)。此外,为了实现安全系统控制器还支持扩展为安全模式。
\qquad
寄存器通过CPU专用总线进行访问,以实现快速读/写响应,避免了互连中的临时阻塞或其他瓶颈。
\qquad
中断分发服务器将所有中断源集中起来,然后将具有最高优先级的中断源分派给各个CPU。GIC确保一个针对多个CPU的中断一次只能被一个CPU执行。所有中断源都由唯一的中断ID号标识。所有中断源都有自己的可配置优先级和目标CPU列表。
4、软件中断SGI
\qquad
每个CPU可以自己产生中断,也可以由其他CPU产生中断,或者使用软件生成中断(SGI),共有16个SGI。通过写SGI中断号到ICDSGIR寄存器和指定的目标CPU可以生成一个SGI。这个写操作通过CPU专用总线完成。每个CPU有至多16个SGI。中断的清除操作是通过读取ICCIAR寄存器或写1到ICDICPR寄存器的相应bit位。所有的SGI是边沿触发,敏感类型是固定不可更改的。ICDICFR0寄存器是只读的,因为它指定了所有16个SGIs的敏感性类型。
5、私有外设中断PPI
\qquad
每个CPU连接五个私有的外设中断。
\qquad
PPI的敏感类型是固定不可更改的,因此ICDICFR1寄存器是只读模式。需要注意的是从PL来的快速中断信号(FIQ)和中断信号(IRQ)是被反向后送入中断控制器的。因此,尽管在ICDICFR1寄存器映射出它们是低有效,但它们在PS-PL接口是高有效的。
6、共享外设中断SPI
\qquad
可将来自各个模块的约60个中断路由到CPUs或PL。中断控制器为cpu管理这些中断的优先级和接收。
\qquad
除了IRQ #61到#68和#84到#91之外,所有的中断敏感类型(rising edge/High level)都是固定不能改变。GIC必须被编程来适应这一点。BootROM不会对这些寄存器进行编程,因此SDK设备驱动程序必须对GIC进行编程以适应这些敏感类型。
\qquad
对于电平敏感类型的中断,请求源必须为中断处理程序提供一种机制,以便在中断被确认后清除中断。这一要求适用于任何高电平敏感类型的IRQF2Pn。
\qquad
对于边缘敏感类型的中断,请求源必须提供足够宽的脉冲以便GIC捕获。这通常至少是2个CPU_2x3x周期。这个要求适用于任何情况IRQF2Pn具有上升边缘灵敏度类型的中断。
\qquad
ICDICFR2通过ICDICFR5寄存器配置所有SPI的中断类型。每个中断有一个2bit字段,它指定了敏感类型和处理模型。
7、中断敏感类型、目标和处理方式
\qquad
有三种类型的中断:SPI, PPI和SGI。一般来说,中断信号包括一个敏感类型设置,一个或两个CPU处理中断,以及哪些CPU是目标:0、1或两者都是。然而,大多数中断信号的功能包括固定的设置,而其他的是部分可编程的。
\qquad
有两个系列寄存器用于配置敏感类型、中断处理和触发目标: mpcore.ICDICFR[5:0]用于配置敏感类型和中断处理,mpcore.ICDIPTR[23:0]用于触发目标。
8、中断优先级
\qquad
所有的中断请求(PPI、SGI和SPI)都被分配一个惟一的ID号。控制器使用ID号进行仲裁。中断分发服务器持有每个中断的挂起中断列表然后选择最高优先级的中断,然后将它发送给CPU接口。具有同等优先级的中断通过选择最低的ID来解决。
\qquad
优先级逻辑在物理上进行了复制,以允许为每个CPU同时选择最高优先级的中断。中断分发程序保存中断、处理器和激活信息的中心列表,并负责向cpu触发软件中断。
\qquad
存储SGI和PPI分发器寄存器,为每个连接的处理器提供单独的副本。硬件确保了针对多个CPU的中断一次只能被一个CPU占用。
\qquad
中断分发服务器向CPU接口传输最高的挂起中断。它接收回已被确认的中断,然后可以改变相应中断的状态。只有确认中断的CPU才能结束中断。
9、中断处理
\qquad
如果在GIC中的中断是挂起的,并且IRQ是失效的,那么GIC中的中断将变为非活动的(CPU永远不会看到它)。
\qquad
如果在GIC中中断是有效的(因为CPU接口已经确认了中断),那么软件ISR首先通过检查GIC寄存器判断中断源,然后轮询I/O外设中断状态寄存器来确定原因。
10、中断程序设计实现步骤
1) 设置中断向量表和解析程序;
2) 对中断源进行配置;
3) 中断分配器(ICD)初始化;
4) 中断控制器(ICC)初始化;
5) 中断分配器(ICD)配置;
6) CPSR寄存器进行配置;
7) 中断服务程序设计;
11、PL-PS中断实例
\quad
PL触发PS中断,中断为电平敏感。
1)BD配置及连线
\quad
在中断窗口中选中PL-PS通用中断
\quad
将接口连接到PL端
2)PS端代码
void Init_Gic_Int(void) // 中断寄存器配置
{
int Int_Id = 61; // PL中断为中断列表的第61号
Xil_Out32(0xf8f01184,0xffffffff);//GIC屏蔽中断 ICDICER1
Xil_Out32(0xF8F00108,0x0000000f);// ICCBPR 中断优先级的二进制小数
Xil_ExceptionEnable(); //CPSR中设置允许 IRQ中断
Xil_Out32(0xF8F00110,Int_Id);// ICCEOIR 写中断结束寄存器 PL中断 #61
Xil_Out32(0xF8F0183D,0x00000200);// ICDIPTR 分配中断的CPU接口 #CPU1
Xil_Out32(0xF8F01400+(Int_Id/4)*4,0x000000a0);// ICDIPR 中断优先级 Int_Id=61,优先级设置为0xa0
Xil_Out32(0xF8F00100,0x00000007);// ICCICR CPU接口控制 使用IRQ中断,开所有中断
Xil_Out32(0xF8F00104,0x00000000);//ICCPMR 中断优先级屏蔽 设为0
Xil_Out32(0xf8f01c0c,0x55555555);//中断敏感类型 高电平 ICDICFR3
// 注册中断回调函数 void call_back()
Xil_Out32(0xf8f01104,0xffffffff);//GIC使能中断位 ICDISER1
}
void call_back()
{
// 函数主体
Xil_Out32(0xf8f01284,0x10000000);//ICDICPR1 清中断标志 #61号 PL中断
}
12、寄存器表
名字 | 寄存器描述 | 绝对地址 |
---|---|---|
ICCICR | CPU接口控制 | 0xf8f00100 |
ICCPMR | 中断优先级屏蔽 | 0xf8f00104 |
ICCBPR | 用于中断优先级的二进制小数点 | 0xf8f00108 |
ICCIAR | 中断响应 | 0xf8f0010c |
ICCEOIR | 中断结束 | 0xf8f00110 |
ICCRPR | 运行优先级 | 0xf8f00114 |
ICCHPIR | 最高待处理的中断 | 0xf8f00118 |
ICCABPR | 非安全二进制小数点寄存器别名 | 0xf8f0011c |
ICCIDR(ro) | CPU 接口实现者识别寄存器 | 0xf8f001fc |
ICDDCR | 发布控制寄存器 | 0xf8f01000 |
ICDICTR(ro) | 控制器实现 | 0xf8f01004 |
ICDIIDR(ro) | 控制器实现 | 0xf8f01008 |
ICDISR0 | 中断安全 | 0xf8f01080 |
ICDISER0 | 中断设置使能0 | 0xf8f01100 |
ICDISER1 | 中断设置使能1 | 0xf8f01104 |
ICDISER2 | 中断设置使能2 | 0xf8f01108 |
ICDICER0 | 中断清除0 | 0xf8f01180 |
ICDICER1 | 中断清除1 | 0xf8f01184 |
ICDICER2 | 中断清除2 | 0xf8f91188 |
ICDISPR0 | 中断设置待处理 | 0xf8f01200 |
ICDISPR1 | 中断设置待处理 | 0xf8f01204 |
ICDISPR2 | 中断设置待处理 | 0xf8f01208 |
ICDICPR0 | 清除待处理 | 0xf8f01280 |
ICDICPR1 | 清除待处理 | 0xf8f01284 |
ICDICPR2 | 清除待处理 | 0xf8f01288 |
ICDABR0 | 中断活动 | 0xf8f01300 |
ICDABR1 | 中断活动 | 0xf8f01304 |
ICDABR2 | 中断活动 | 0xf8f01308 |
ICDIPRn | 中断优先级 | 0xf8f01400 ~ 0xf8f01428 |
ICDIPTRn(ro) | 中断目标 | 0xf8f01800 ~ 0xf8f0185c |
ICDICFR0(ro) | SGI触发敏感类型配置 | 0xf8f01c00 |
ICDICFR1 | PPI触发敏感类型配置 | 0xf8f01c04 |
ICDICFR2~5 | SPI触发敏感类型配置 | 0xf8f01c08 ~ 0xf8f01c14 |
ICDSGIR | SGI寄存器 | 0xf8f01f00 |