ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

ZYNQ中断过程分析

2021-01-01 12:29:05  阅读:563  来源: 互联网

标签:分析 中断过程 INT Xil XScuGic INTCInst ZYNQ SW1 ID


以下面代码为例

#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)

标签:分析,中断过程,INT,Xil,XScuGic,INTCInst,ZYNQ,SW1,ID
来源: https://blog.csdn.net/qq_40268672/article/details/112059407

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有