中断基本概念
ZYNQ使用的ARM处理器中,中断是异常的一种,共7种异常,通常所说的中断即IRQ异常:
#define XIL_EXCEPTION_ID_RESET 0U
#define XIL_EXCEPTION_ID_UNDEFINED_INT 1U
#define XIL_EXCEPTION_ID_SWI_INT 2U
#define XIL_EXCEPTION_ID_PREFETCH_ABORT_INT 3U
#define XIL_EXCEPTION_ID_DATA_ABORT_INT 4U
#define XIL_EXCEPTION_ID_IRQ_INT 5U
#define XIL_EXCEPTION_ID_FIQ_INT 6U
#define XIL_EXCEPTION_ID_LAST 6U
启用PL到PS的中断
在PS设置中勾选IRQ_F2P,可以看到中断ID的范围:[91:84],[68:61]
共16个中断,这16个中断的ID的宏定义可以在xparameters_ps.h文件中找到。
多个中断源的连接方法
默认情况下,IRQ_F2P是1位宽。通过IP核concat连接多个中断源,IRQ_F2P的位宽会随concat的位宽自动改变。
中断初始化
//中断控制器驱动的实例
XScuGic Intc; /* The Instance of the Interrupt Controller Driver */
//声明配置结构指针IntcConfig
XScuGic_Config *IntcConfig;
//通过INTC_DEVICE_ID给配置结构指针赋值
IntcConfig = XScuGic_LookupConfig(XPAR_SCUGIC_SINGLE_DEVICE_ID);//
//使用配置结构配置中断
Result = XScuGic_CfgInitialize(&Intc, \
IntcConfig, \ //配置结构
IntcConfig->CpuBaseAddress); //
//设置中断优先级 以及 上升沿触发
//优先级的最大值 #define XSCUGIC_MAX_INTR_PRIO_VAL 248U
XScuGic_SetPriorityTriggerType(&Intc, XPS_FPGA0_INT_ID, 0xA0, 0x3);
//注册中断服务函数,即中断源与中断服务函数连接
Result = XScuGic_Connect(&Intc,
XPS_FPGA0_INT_ID, \
(Xil_ExceptionHandler)IntHandler, \
&Intc);
//使能中断,对于ZYNQ,中断ID取值范围0~95
XScuGic_Enable(&Intc, XPS_FPGA0_INT_ID);
//异常初始化及
//void Xil_ExceptionInit(void)
//{
// return;
//}
Xil_ExceptionInit();//兼容早期BSP
//异常服务函数注册
//#define XIL_EXCEPTION_ID_RESET 0U
//#define XIL_EXCEPTION_ID_UNDEFINED_INT 1U
//#define XIL_EXCEPTION_ID_SWI_INT 2U
//#define XIL_EXCEPTION_ID_PREFETCH_ABORT_INT 3U
//#define XIL_EXCEPTION_ID_DATA_ABORT_INT 4U
//#define XIL_EXCEPTION_ID_IRQ_INT 5U
//#define XIL_EXCEPTION_ID_FIQ_INT 6U
//#define XIL_EXCEPTION_ID_LAST 6U
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT, \ //ARM处理器的IRQ中断ID
(Xil_ExceptionHandler)XScuGic_InterruptHandler, \ //即主中断服务函数XScuGic_InterruptHandler,用于确定中断源
&Intc);
//使能异常
Xil_ExceptionEnable();
中断服务函数
void GpioHandler(void *CallbackRef)
{
xil_printf("CallbackRef=%d\r\n", CallbackRef);
XGpio *GpioPtr = (XGpio *)CallbackRef;
...
// --- 清除中断
XGpio_InterruptClear(GpioPtr, GlobalIntrMask);
}