您的位置:首页 > 其它

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

2018-02-11 16:25 369 查看
设计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_1XPAR_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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: