ZYNQ 定时器中断实验——FPGA Vitis篇

本文转载自: FpgaHome微信公众号

1. 前言

本实验介绍如何使用ZYNQ芯片PS端的定时器资源。通过定时器来每秒触发一次定时器中断,并通过中断服务函数给串口打印一条信息。

ZYNQ芯片中有两个Cortex-A9处理器,每个Cortex-A9处理器都有自己私有的32位定时器和32位看门狗定时器。两个处理器共享一个64位的全局定时器。这些定时器的工作时钟频率为CPU工作时钟频率的一半。

本实验使用的定时器为Cortex-A9处理器的私有定时器,即下图中的“CPU Private Timer”,ZYNQ定时器结构图如下图所示:

2. 中断介绍

Zynq中断大致可分为三个部分,如下图所示:

第一部分,SGI,软件生成的中断,共16个端口;

第二部分,为PPI,CPU私有外设中断,有5个;

第三部分,为 SPI,共享外设中断,来自于44个PS端的IO外设以及16个PL端的中断。

中断控制器(GIC),用于对中断进行使能、关闭、掩码、设置优先等。

以下为中断控制器框图,主要的控制器部分为ICC和ICD,ICC连接SGI和PPI, ICD连接SPI,可配置两者的寄存器来控制中断。

2.1. SGI中断(软件产生中断)

每个CPU可以使用软件生成的中断(SGI)中断自己、另一个CPU或两个CPU。软件产生的中断共有16个,如下表所示。 通过编写SGI中断号至ICDSGIR寄存器可以指定相应的CPU产生SGI中断。

2.2. PPI中断(CPU私有外设中断)

每个CPU有5个私有的外设中断,如下表所示,共5个IRQ ID号。

2.3. SPI中断

共享的外设中断如下表所示,共60个IRQ ID号。


3. Vivado工程编写

虽然本实验仅仅使用了FPGA的PS端,但是还要建立一个Vivado工程,用来配置PS管脚。虽然PS端的ARM是硬核,但是在ZYNQ当中也要将ARM硬核添加到工程当中才能使用。本实验使用的Vivado版本为Vivado2021.1。

本实验使用的Vivado工程同《ZYNQ 串口打印输出——FPGA Vitis篇》中使用的Vivado工程相同,大家可以查看该文章来了解Vivado工程的建立。

4. Vitis工程编写

(1)打开Vitis工程;

Vitis工程也延用《ZYNQ 串口打印输出——FPGA Vitis篇》中使用的Vitis工程。打开Vitis工程,点击“Board Support Package”,通过选择“ps7_scutimer_0”的“Import Examples”,可以导入官方提供的定时器中断例程。


(2)选择“xscutimer_intr_example”,导入定时器中断例程。

(3)通过Xilinx官方文档UG585可知,Cortex-A9处理器自己私有的32位定时器工作时钟频率为CPU工作时钟频率的一半。实验使用的ZedBoard的CPU工作时钟频率为666.667MHz,即定时器的时钟频率为333.333MHz。

因此,如果我们想实现每1秒钟触发1次定时器中断,可以将“TIMER_LOAD_VALUE”宏修改为333333333。

(4)我们想让定时器每1秒触发一次中断,并且触发10次后停止。需要修改的代码如下:

“ScuTimerIntrExample”函数中,将TimerExpired次数修改为10。

“TimerIntrHandler”函数中,增加打印信息,将TimerExpired次数修改为10。

(5)编译工程,将工程下载到硬件板卡上(编译和下载方式见《ZYNQ 串口打印输出——FPGA Vitis篇》),打开串口助手。串口助手将在每秒收到板卡发来的信息,总共收到10次。

5. 实验总结

了解一下中断控制器的使用,主要分为几个步骤:

(1)初始化中断控制器GIC;

(2)初始化中断异常;

(3)中断服务函数注册;

(4)在中断控制器中使能中断;

(5)使能外设中断;

(6)使能中断异常。

有两步需要注意,在中断控制器中使能中断是要根据中断号使能相应的中断,比如本实验介绍的Timer为私有定时器,中断号为29,是在中断控制器GIC中的操作。

如果是外设中断,需要在外设中打开它的中断,正常情况下是不打开的,打开之后就可以产生中断传递到中断控制器GIC。

6. 工程源码下载

本文使用的工程可以通过在公众号输入 ZYNQ_TIMER 来获取工程下载链接,工程使用的vivado版本为2021.1。

最新文章

最新文章