Zynq 自定义模块中断触发实例

设计PL与PS数据交互,用到自定义IP模块,同时需要给ARM侧一个ACK信号,考虑到实时性,采用PL-PS的IRQ。

参考官网文档:

The_Zynq_Book_ebook.pdf

UG111 Embedded System Tools Reference Manual.pdf 的Interrupt Management部分

得到中断处理基本流程:(具体函数参考 SCUGIC API)

    1)中断初始化

    2 )  调用中断建立函数

    3)Xilinx中断触发使能

    4)连接中断操作函数

   5)配置中断触发信号

    6)使能中断控制器

    下面是中断触发实

/*
 * helloworld.c: simple test application
 *
 * This application configures UART 16550 to baud rate 9600.
 * PS7 UART (Zynq) is not initialized by this application, since
 * bootrom/bsp configures it to baud rate 115200
 *
 * ------------------------------------------------
 * | UART TYPE   BAUD RATE                        |
 * ------------------------------------------------
 *   uartns550   9600
 *   uartlite    Configurable only in HW design
 *   ps7_uart    115200 (configured by bootrom/bsp)

 */

#include <stdio.h>
#include "platform.h"
#include "xscugic.h"
#include "xil_exception.h"
#include "xparameters.h"
#include "pthread.h"

#define INT_CFG0_OFFSET  0x00000C00
#define BRAM_CTRL_1 XPAR_AXI_BRAM_CTRL_1_S_AXI_BASEADDR
#define BRAM_CTRL_2 XPAR_AXI_BRAM_CTRL_2_S_AXI_BASEADDR

// Parameter definitions
#define MM2S_INT_ID             61
#define S2MM_INT_ID             62
#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 XScuGic_Config *IntcConfig;
//pthread_t thread_tx;

static void MM2S_intr_Handler(void *param);
static void S2MM_intr_Handler(void *param);
static void IntcTypeSetup(XScuGic *InstancePtr, int intId, int intType);
static int IntcInitFunction(u16 DeviceId);

static void MM2S_intr_Handler(void *param)
{
    int sw_id = (int)param;
    int num, rev;
    printf("------ MM2S of %d Interrupt ----- \n\r", sw_id);
    for(num = 0; num<15; num++)
    {
         rev = Xil_In32(BRAM_CTRL_1 + num*4);
         printf( "The data at %x is %x \n\r",BRAM_CTRL_1 + num*4,rev);
    }
}

static void S2MM_intr_Handler(void *param)
{
    int sw_id = (int)param;
    int num, rev;
    printf("------ S2MM of %d Interrupt ----- \n\r", sw_id);
    for(num = 0; num<15; num++)
    {
         rev = Xil_In32(BRAM_CTRL_2 + num*4);
         printf( "The data at %x is %x \n\r",BRAM_CTRL_2 + num*4,rev);
    }
}

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)
{
    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 MM2S and S2MM interrupt to handler
    status = XScuGic_Connect(&INTCInst,
                                              MM2S_INT_ID,
                                            (Xil_ExceptionHandler)MM2S_intr_Handler,
                                            (void *)1);
    if(status != XST_SUCCESS) return XST_FAILURE;

    status = XScuGic_Connect(&INTCInst,
                                             S2MM_INT_ID,
                                             (Xil_ExceptionHandler)S2MM_intr_Handler,
                                             (void *)2);

    if(status != XST_SUCCESS) return XST_FAILURE;
    // Set interrupt type of MM2S and S2MM to rising edge
    IntcTypeSetup(&INTCInst, MM2S_INT_ID, INT_TYPE_RISING_EDGE);
    IntcTypeSetup(&INTCInst, S2MM_INT_ID, INT_TYPE_RISING_EDGE);

    // Enable MM2S and S2MM interrupts in the controller
    XScuGic_Enable(&INTCInst, MM2S_INT_ID);
    XScuGic_Enable(&INTCInst, S2MM_INT_ID);

    return XST_SUCCESS;
}

int main(void)
{
    init_platform();
    printf("--------PL inttrupt test----------\n\r");
    IntcInitFunction(INTC_DEVICE_ID);
   //    pthread_create(&thread_tx, NULL, &MM2S_intr_Handler, NULL);

    while(1){
             // WAIT
        };

    cleanup_platform();
    return 0;
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值