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設計決定。
在這里插入圖片描述
在這里插入圖片描述


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM