Zedboard上涉及多个嵌套中断的情况, 只要按照中断添加的routine, 嵌套不需要手动修改Mask, 自动就ok了.我目前的一个典型应用是:
设计的FPGA相当于对PS也就是Arm上程序做加速, 分析加速比的时候,需要测量软硬件的执行时间,因此需要timer中断, 另外数据的DMA传输需要DMA中断, 计算完成标识也有ComputationDone中断. 使用如下中断设置处理模板即可. 之前由于看到timer有另外独立的一套中断初始化函数,比如ScuTimer_EnableInterrupt(PSTimerPtr);不过,直接无视之, 只需要个中断号, 添加进去这个半完成的函数就ok了,中断ISR自己来写正合适.
int InterruptionSetup(XScuGic *XGicPtr, XDmaPs *XDmaPtr) {
int Status;
XScuGic_Config *GicConfig;
/*
* Initialize the interrupt controller driver so that it is ready to
* use.
*/
GicConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
if (NULL == GicConfig) {
return XST_FAILURE;
}
Status = XScuGic_CfgInitialize(XGicPtr, GicConfig,
GicConfig->CpuBaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
//XScuGic_SetPriorityTriggerType(XGicPtr, COMPUTATION_DONE_INTR, 0xA0, 0x3);
/*
* Connect the interrupt controller interrupt handler to the hardware
* interrupt handling logic in the processor.
*/
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
(Xil_ExceptionHandler) XScuGic_InterruptHandler, XGicPtr);
/*
* Connect the device driver handlers that will be called when an interrupt
* for the device occurs, the device driver handler performs the specific
* interrupt processing for the device
*/
//Connect to the Computation done ISR
/*Status=XScuGic_Connect(XGicPtr, COMPUTATION_DONE_INTR,
(Xil_ExceptionHandler)CompDoneISR, &XGio);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}*/
/*Connect the timer interruption ISR*/
Status = XScuGic_Connect(XGicPtr, TIMER_IRPT_INTR,
(Xil_ExceptionHandler) TimerIntrHandler, (void *)&PSTimer);
/* Connect the Fault ISR */
Status = XScuGic_Connect(XGicPtr, DMA_FAULT_INTR,
(Xil_InterruptHandler) XDmaPs_FaultISR, (void *) XDmaPtr);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/* Connect the Done ISR for all 8 channels of DMA 0 */
Status = XScuGic_Connect(XGicPtr, DMA_DONE_INTR_0,
(Xil_InterruptHandler) XDmaPs_DoneISR_0, (void *) XDmaPtr);
Status |= XScuGic_Connect(XGicPtr, DMA_DONE_INTR_1,
(Xil_InterruptHandler) XDmaPs_DoneISR_1, (void *) XDmaPtr);
Status |= XScuGic_Connect(XGicPtr, DMA_DONE_INTR_2,
(Xil_InterruptHandler) XDmaPs_DoneISR_2, (void *) XDmaPtr);
Status |= XScuGic_Connect(XGicPtr, DMA_DONE_INTR_3,
(Xil_InterruptHandler) XDmaPs_DoneISR_3, (void *) XDmaPtr);
Status |= XScuGic_Connect(XGicPtr, DMA_DONE_INTR_4,
(Xil_InterruptHandler) XDmaPs_DoneISR_4, (void *) XDmaPtr);
Status |= XScuGic_Connect(XGicPtr, DMA_DONE_INTR_5,
(Xil_InterruptHandler) XDmaPs_DoneISR_5, (void *) XDmaPtr);
Status |= XScuGic_Connect(XGicPtr, DMA_DONE_INTR_6,
(Xil_InterruptHandler) XDmaPs_DoneISR_6, (void *) XDmaPtr);
Status |= XScuGic_Connect(XGicPtr, DMA_DONE_INTR_7,
(Xil_InterruptHandler) XDmaPs_DoneISR_7, (void *) XDmaPtr);
if (Status != XST_SUCCESS)
return XST_FAILURE;
/*Enable the interrupts for the device*/
XScuGic_Enable(XGicPtr, DMA_DONE_INTR_0);
XScuGic_Enable(XGicPtr, DMA_DONE_INTR_1);
XScuGic_Enable(XGicPtr, DMA_DONE_INTR_2);
XScuGic_Enable(XGicPtr, DMA_DONE_INTR_3);
XScuGic_Enable(XGicPtr, DMA_DONE_INTR_4);
XScuGic_Enable(XGicPtr, DMA_DONE_INTR_5);
XScuGic_Enable(XGicPtr, DMA_DONE_INTR_6);
XScuGic_Enable(XGicPtr, DMA_DONE_INTR_7);
XScuGic_Enable(XGicPtr, DMA_FAULT_INTR);
XScuGic_Enable(XGicPtr, TIMER_IRPT_INTR);
//XScuTimer_EnableInterrupt(PSTimerPtr);
Xil_ExceptionInit();
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler) XScuGic_InterruptHandler, XGicPtr);
Xil_ExceptionEnable();
return XST_SUCCESS;
}