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

ZYNQ中断分为3类:

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设计决定。
在这里插入图片描述
在这里插入图片描述

posted @ 2022-03-02 09:23  solonj  阅读(5756)  评论(0编辑  收藏  举报