网游活动情报网 - 新服预约与福利指南

ZYNQ:SGI、PPI、SPI三种中断的实例(含代码)

ZYNQ中断分为3类:

SGI(Software Generated Interrupts)软件中断

PPI(Private Peripheral Interrupts)私有外设中断

SPI(Shared Peripheral Interrupts)共享外设中断

1、SGI软件中断

16个,中断号:0—15。通过向ICDSGIR寄存器写入SGI中断号、CPU ID,来产生一个软件中断;通过读ICCIAR寄存器或者向ICDICPR寄存器相应的比特位写1,可以清除中断。所有的SGI为边沿触发。

2、PPI私有外设中断

每个CPU(CPU0、CPU1)连接5个私有中断,中断号:27—31。ICDICFR1为PPIs的优先级及触发条件控制寄存器,是只读的,因而PPIs的触发条件也不可更改。需要注意到的是,PL部分的快速响应中断FIQ(fast interrupt)信号与普通中断IRQ(interrupt)需要被送往中断控制器中,所以即便ICDICFR1规定IRQ与FIQ的响应等级为low level,但是他们的在PS与PL接口的响应等级仍是high。

3、SPI共享外设中断

中断号:32-95。由PS和PL上的各种I/O控制器和存储器控制器产生,如GPIO、DMA、定时器等模块的中断信号,这些中断信号会被路由到CPU。PS的外设产生的SPI中断也会路由到PL上。

中断发生时执行的中断函数:

static void XXXIntrHandler(void *CallBackRef)

以下代码会汇总,不可直接使用:

XScuGic xScuGic;//XScuGic 驱动程序实例数据。用户需要为系统中的每个intc设备分配一个这种类型的变量。然后,该类型变量的指针被传递给驱动程序API函数。

XScuTimer_Config *ConfigPtr;

XUartPs_Config *XUartPs_Config_uart1;

XScuGic_Config *XScuGic_Config_ps;

//PPI 私有定时器初始化

ConfigPtr = XScuTimer_LookupConfig(TIMER_DEVICE_ID);

Status = XScuTimer_CfgInitialize(&TimerInstance, ConfigPtr,

ConfigPtr->BaseAddr);

//PPI 私有定时器设置

Status = XScuTimer_SelfTest(&TimerInstance);

/** Set for 1 milli seconds timeout.*/

TimerLoadValue = (XPAR_CPU_CORTEXA9_0_CPU_CLK_FREQ_HZ/2) / 1000;

XScuTimer_LoadTimer( &TimerInstance, TimerLoadValue );

XScuTimer_EnableAutoReload(&TimerInstance);

//0、中断外设初始化

//若中断外设只有一个,该中断外设的初始化,不管用哪几种中断、多少个中断;该初始化只执行一次!!!!!!!!

XScuGic *IntcInstancePtr = &xScuGic; /* Instance of the Interrupt Controller */

XScuGic_Config *IntcConfig;

IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);

Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,

IntcConfig->CpuBaseAddress);

Xil_ExceptionInit();

Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,

(Xil_ExceptionHandler)XScuGic_DeviceInterruptHandler,

(void *)INTC_DEVICE_ID);

//1、PPI 私有定时器中断设置 方法1

XScuGic_RegisterHandler(INTC_BASE_ADDR, TIMER_IRPT_INTR,

(Xil_ExceptionHandler)timer_callback,

(void *)&TimerInstance);

XScuGic_EnableIntr(INTC_DIST_BASE_ADDR, TIMER_IRPT_INTR);

XScuTimer_EnableInterrupt(&TimerInstance);

XScuTimer_Start(&TimerInstance);

//1、PPI 私有定时器中断设置 方法2

XScuGic_Connect(GicInstancePtr, TimerIntrId,

(Xil_ExceptionHandler)TimerIntrHandler,//set up the timer interrupt

(void *)TimerInstancePtr);

XScuGic_Enable(GicInstancePtr, TimerIntrId);//enable the interrupt for the Timer at GIC

XScuTimer_EnableInterrupt(&TimerInstance);

XScuTimer_Start(&TimerInstance);

//2、SPI 开关设为中断

status = XScuGic_Connect(&INTCInst,SW1_INT_ID,

(Xil_ExceptionHandler)SW_intr_Handler,(void *)1);

IntcTypeSetup(&INTCInst, SW1_INT_ID, INT_TYPE_RISING_EDGE);

XScuGic_Enable(&INTCInst, SW1_INT_ID);

//3、SGI 软件中断

status = XScuGic_Connect(&ScuGic,

CPU0_SW_INTR(Xil_ExceptionHandler)cpu0IntrHandler,

&ScuGic);

XScuGic_Enable(&ScuGic,CPU0_SW_INTR);

//

Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ); //等于Xil_ExceptionEnable();

各种使能函数汇总:

//各个中断的使能

XScuGic_EnableIntr(INTC_DIST_BASE_ADDR, TIMER_IRPT_INTR);//等于XScuGic_Enable();

XScuGic_Enable(&INTCInst, SW1_INT_ID);

XScuGic_Enable(&ScuGic, CPU0_SW_INTR);

//单个外设的使能

XScuTimer_EnableInterrupt(&TimerInstance);

//中断总外设的使能

Xil_ExceptionEnableMask(XIL_EXCEPTION_IRQ); //等于Xil_ExceptionEnable();

Xil_ExceptionEnable();

网上找到了下面三个极简的例子,可以很好的帮助学习基础。

一、SGI 中断实例:

基于ZYNQ的中断的使用(1)

使用中断号:13、14。SGI实验的中断号可在范围内自定义。

二、PPI 中断实例:

S02_CH08_ ZYNQ 定时器中断实验

使用中断号:29。PPI实验的中断号可在xparameters_ps.h查找。

/* Private Peripheral Interrupts (PPI) */

#define XPS_GLOBAL_TMR_INT_ID 27 /* SCU Global Timer interrupt */

#define XPS_FIQ_INT_ID 28 /* FIQ from FPGA fabric */

#define XPS_SCU_TMR_INT_ID 29 /* SCU Private Timer interrupt */

#define XPS_SCU_WDT_INT_ID 30 /* SCU Private WDT interrupt */

#define XPS_IRQ_INT_ID 31 /* IRQ from FPGA fabric */

三、SPI 中断实例:

S02_CH07_ ZYNQ PL中断请求

使用中断号:61、62。SPI实验的中断号由PL设计决定。

![在这里插入图片描述]( https://img-blog.csdnimg.cn/20200720152722324.png?x-oss-process=image/watermark ,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0xJVTk0NDYwMjk2NQ==,size_16,color_FFFFFF,t_70)