本学习笔记参考UG585-Zynq-7000-TRM.pdf ch.7:Interrupts。文中有说的不够严谨或者是有错误的地方,欢迎指正!
zynq中的interrupts有很多种,大体上分为三类:private、shared、software interrupts。
1.zynq 7000 有两个Cortex-A9 processor,每个cpu 都有一系列的private peripheral interrupts(PPIs,私有外围中断)。
PPIs包含:global timer、private watchdog timer、private timer 和来自PL部分的FIQ/IRQ(FIQ,是fast interrupt,IRQ是一般性的)。来自PL中的FIQ/IRQ可以作为 PPI#4 和 PPI #1通过GIC,也可以绕过GIC,通过pass-through multiplexer进入CPU。
在mpcore.ICCICR寄存器中可以使能pass-through 模式。
Software generated interrupts(SGIs):可以连接到一个或者两个cpu,是通过向generic interrupt controller(GIC)中的寄存器写内容产生的。
Shared peripheral interrupts(SPIs):该中断来自PS部分各种各样的IO外设,以及PL部分。
2.Generic Interrupt Controller(GIC)
GIC是管理中断的中央元,它将来自PS或者PL部分的中断发送给CPU。其功能:enables\disables\masks\prioritizes 中断源,将这些中断发送给选定的CPU。同时支持security extension。
每个中断都有独一无二的中断ID号,所有的中断都可以配置优先级,以及选定将中断信号给哪个CPU。这些配置是通过控制寄存器来完成的,CPU通过cpu private bus 来access中断控制和状态寄存器(图中右下角所示)。
3.GIC复位是通过向PERI_RST bit写数来完成的,PERI_RST是SLCR 中A9_CPU_RST_CTRL中的一位。这个复位信号同时会复位cpu private timer以及private watchdog timer。
4.接下来详细说一下这三种中断
(1)SGI:每个cpu都可以通过SGI来中断它自己,或者其他cpu,或者中断两个cpu,一共有16个SGI,IRQ ID# 范围是0~15。
(a)那么中断过程是如何触发的?
通过将SGI中断号写入到ICDSGIR中的SGIINTID这4位,再设置好接收中断的cpu就可以产生SGI中断了。写的过程是通过CPU的private bus来完成的。
(b)如何设置中断类型?
所有的SGI的中断类型都是rising edge,都是固定的,不能够修改,因此ICDICFR0(Interrupt configuration register)只能够read-only。
(c)中断发送到哪个CPU呢?
发送到哪个CPU interface由ICDSGIR中的CPUTargetList这8位决定,这里ICDIPTR0至ICDIPTR3都是只读的。
(d)中断完成后,如何清除中断呢?
通过读ICCIAR(Interrupt acknowledge)寄存器,或者向ICDICPR(Clear-pending)中写1来完成。
(2)PPI:PPI是每个CPU的私有中断,上文中提到了PPI包含global timer、private timer、private watchdog timer和来自PL的FIQ和IRQ。每个CPU有5个这样的私有中断。
(a)如何设置中断类型?
所有的PPI的中断类型都是固定的,不能够修改,有rising和active low level两种,因此ICDICFR1(Interrupt configuration register)也只能够read-only。
注意:来自PL的FIQ和IRQ信号进行反转后送入了中断控制器,所以所谓ICDICFR1寄存器显示active low level,他们在PS-PL接口处也是active high,也就是高电平触发中断。
(b)中断发送到哪个CPU呢?
由于PPI是每个CPU的私有中断,所有只有对应的CPU可以响应。
所以ICDIPTR[7:4]是reserved。
(c)中断完成后,如何清除中断呢?
对于高电平触发的,需要有interrupt handler来清除中断。
(3)SPI:SPI中断比较多,中断控制寄存器需要设置优先级和接收中断的CPU。
(a)如何设置中断类型?
除了IRQ #61~#68 和IRQ#84~91 是可以修改的以外,其他中断的触发类型都是固定的,是不可以修改的。
在ICDICFR中对触发类型进行设置,如下图:
(b)中断发送到哪个CPU呢?
(c)中断完成后,如何清除中断呢?
对于高电平触发的中断类型,需要请求源提供machanism用于有interrupt handler来清除中断。
(4)其他:上述说的ICDICFR用来设置触发类型(针对于可以修改触发类型的中断源),ICDIPTR用来设置接收中断的CPU。除了这些寄存器以外,还需要其他的寄存器用来设置其他参数,如优先级的设置需要使用ICDIPR、中断使能ICDICER、中断失能ICDICER、中断安全ICDISR等。
上文中有说的不够严谨或者是有错误的地方,欢迎指正!