ZYNQ中断过程分析
分析 ZYNQ
2023-09-14 09:10:01 时间
以下面代码为例
#include <stdio.h>
#include "platform.h"
#include "xscugic.h"
#include "xil_exception.h"
#define INT_CFG0_OFFSET 0x00000C00
// Parameter definitions
#define SW1_INT_ID 61
#define SW2_INT_ID 62
#define SW3_INT_ID 63
#define INTC_DEVICE_ID XPAR_PS7_SCUGIC_0_DEVICE_ID
#define INT_TYPE_RISING_EDGE 0x03
#define INT_TYPE_HIGHLEVEL 0x01
#define INT_TYPE_MASK 0x03
static XScuGic INTCInst;
static void SW_intr_Handler(void *param);
static int InterruptSystemSetup(XScuGic *XScuGicInstancePtr);
static int IntcInitFunction(u16 DeviceId);
static void SW_intr_Handler(void *param)
{
int sw_id = (int)param;
printf("SW%d int\n\r", sw_id);
}
void IntcTypeSetup(XScuGic *InstancePtr, int intId, int intType)
{
int mask;
intType &= INT_TYPE_MASK;
mask = XScuGic_DistReadReg(InstancePtr, INT_CFG0_OFFSET + (intId/16)*4);
mask &= ~(INT_TYPE_MASK << (intId%16)*2);
mask |= intType << ((intId%16)*2);
XScuGic_DistWriteReg(InstancePtr, INT_CFG0_OFFSET + (intId/16)*4, mask);
}
int IntcInitFunction(u16 DeviceId)
{
XScuGic_Config *IntcConfig;
int status;
// Interrupt controller initialisation
IntcConfig = XScuGic_LookupConfig(DeviceId);
status = XScuGic_CfgInitialize(&INTCInst, IntcConfig, IntcConfig->CpuBaseAddress);
if(status != XST_SUCCESS) return XST_FAILURE;
// Call to interrupt setup
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
&INTCInst);
Xil_ExceptionEnable();
// Connect SW1~SW3 interrupt to handler
status = XScuGic_Connect(&INTCInst,
SW1_INT_ID,
(Xil_ExceptionHandler)SW_intr_Handler,
(void *)1);
if(status != XST_SUCCESS) return XST_FAILURE;
status = XScuGic_Connect(&INTCInst,
SW2_INT_ID,
(Xil_ExceptionHandler)SW_intr_Handler,
(void *)2);
if(status != XST_SUCCESS) return XST_FAILURE;
status = XScuGic_Connect(&INTCInst,
SW3_INT_ID,
(Xil_ExceptionHandler)SW_intr_Handler,
(void *)3);
if(status != XST_SUCCESS) return XST_FAILURE;
// Set interrupt type of SW1~SW3 to rising edge
IntcTypeSetup(&INTCInst, SW1_INT_ID, INT_TYPE_RISING_EDGE);
IntcTypeSetup(&INTCInst, SW2_INT_ID, INT_TYPE_RISING_EDGE);
IntcTypeSetup(&INTCInst, SW3_INT_ID, INT_TYPE_RISING_EDGE);
// Enable SW1~SW3 interrupts in the controller
XScuGic_Enable(&INTCInst, SW1_INT_ID);
XScuGic_Enable(&INTCInst, SW2_INT_ID);
XScuGic_Enable(&INTCInst, SW3_INT_ID);
return XST_SUCCESS;
}
int main(void)
{
init_platform();
print("PL int test\n\r");
IntcInitFunction(INTC_DEVICE_ID);
while(1);
cleanup_platform();
return 0;
}
这里主要分析这两个函数
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
(Xil_ExceptionHandler)XScuGic_InterruptHandler,
&INTCInst);
Xil_ExceptionEnable();
// Connect SW1~SW3 interrupt to handler
status = XScuGic_Connect(&INTCInst,
SW1_INT_ID,
(Xil_ExceptionHandler)SW_intr_Handler,
(void *)1);
首先,我们看到中断向量表
执行2之后,进行中断的处理,IRQInterrupt的具体行为是:
而Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,(Xil_ExceptionHandler)XScuGic_InterruptHandler,&INTCInst);
有如下行为:
结合IRQInterrupt函数,总的行为应该是
XScuGic_InterruptHandler(&INTCInst)
再来看
status = XScuGic_Connect(&INTCInst,
SW1_INT_ID,
(Xil_ExceptionHandler)SW_intr_Handler,
(void *)1);
结合函数源码
有
INTCInst->Config->HandlerTable[SW1_INT_ID].Handler=SW_intr_Handler
INTCInst->Config->HandlerTable[SW1_INT_ID].CallBackRef=1
再结合**XScuGic_InterruptHandler(&INTCInst)
**的源码:
可知,最终执行了
SW_intr_Handler(1)
相关文章
- PostgreSQL 实时位置跟踪+轨迹分析系统实践 - 单机顶千亿轨迹/天
- js 原型的内存分析
- SAP 电商云和 Customer Data Cloud(CDC) 的登录集成过程中的一些问题分析
- 关于静态分析技术符号执行,从一个故事讲起······
- 【Android 逆向】整体加固脱壳 ( DEX 优化流程分析 | DexPrepare.cpp 中 dvmOptimizeDexFile() 方法分析 | /bin/dexopt 源码分析 )
- tpm2-tools源码分析之tpm2_load.c(6)
- 第二人生的源码分析(二十八)UDP发送数据的可靠性控制
- Woreflint恶意软件c2分析
- HCIE-Cloud Computing LAB备考第二步:逐题攻破--第三题:迁移-题目分析
- ZYNQ - 嵌入式Linux开发 -10- ZYNQ启动流程分析
- 【python数据分析】对乐高、奥特曼、高达进行分析,看看哪个卖的最好
- ZYNQ之路--HLS入门示例分析(基于UG871)(一)
- 具体芯片的I2C_Adapter驱动分析