PL-PS FPGA Interrupt for FreeRTOS

how5877 wrote on Friday, July 22, 2016:

I am using freeRTOS in Zedboard. I am able to enable the PL-PS interrupt in bare-metal program. I couldn’t really find any documentation/tutorial on how to link the FreeRTOS and the PL interrupt system. I am currently migrating my software to freeRTOS but I am not sure how to “connect” the interrupt between the freeRTOS and the PL interrupt. Here is what I have done and I am sure it is totally wrong.

In the main:

xTaskCreate(InitInterrupt, (const char * )"Init Interrupt",
            configMINIMAL_STACK_SIZE, XPAR_PS7_SCUGIC_0_DEVICE_ID,
            tskIDLE_PRIORITY, NULL);

Interrupt Enable Function:

XScuGic InterruptController;
static XScuGic_Config *GicConfig;
xSemaphoreHandle DMATransfer_trigger = 0;

int SetUpInterruptSystem(XScuGic *XScuGicInstancePtr) {
    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
            (Xil_ExceptionHandler) XScuGic_InterruptHandler,
            XScuGicInstancePtr);
    Xil_ExceptionEnable();
    //enable interrupt in ARM
    return XST_SUCCESS;
}

static void InitInterrupt( deviceID) {
    while (1) {
        int Status;

        GicConfig = XScuGic_LookupConfig(deviceID);
        if (NULL == GicConfig) {
            xil_printf("Interrupt Initialization FAILED!!\r\n");
            vTaskDelete(NULL);  //delete InitAXIDMA itself
        }

        Status = XScuGic_CfgInitialize(&InterruptController, GicConfig,
                GicConfig->CpuBaseAddress);
        if (Status != XST_SUCCESS) {
            xil_printf("Interrupt Initialization FAILED!!\r\n");
            vTaskDelete(NULL);  //delete InitAXIDMA itself
        }

        Status = SetUpInterruptSystem(&InterruptController);
        if (Status != XST_SUCCESS) {
            xil_printf("Interrupt Initialization FAILED!!\r\n");
            vTaskDelete(NULL);  //delete InitAXIDMA itself
        }

        Status = XScuGic_Connect(&InterruptController,
        XPAR_FABRIC_AXI_DMA_0_S2MM_INTROUT_INTR,
                (Xil_ExceptionHandler) InterruptHandler,
                NULL);
        if (Status != XST_SUCCESS) {
            xil_printf("Interrupt Initialization FAILED!!\r\n");
            vTaskDelete(NULL);  //delete InitAXIDMA itself
        }
        XScuGic_Enable(&InterruptController,
        XPAR_FABRIC_AXI_DMA_0_S2MM_INTROUT_INTR);
#ifdef DEBUG
        xil_printf("Interrupt Initialization Complete\r\n");
#endif
        vTaskDelete(NULL);  //delete InitAXIDMA itself
    }
}

In the interrupt Handler:

void InterruptHandler(void) {
u32 tmpValue;
//xil_printf("Interrupt acknowledged...\n\r);
//clear interrupt just perform a write bit to no 12 ofS2MM_DMASR
tmpValue = Xil_In32(XPAR_AXI_DMA_0_BASEADDR + 0x34);
tmpValue = tmpValue | 0x1000;
Xil_Out32( XPAR_AXI_DMA_0_BASEADDR + 0x34, tmpValue);
//Process Data Here!!

//initialize another transfer
    xSemaphoreGive(DMATransfer_trigger);
}

The interrupt source is from the AXI DMA Controller IP. This is what I have tried but it doesn’t work. Can anyone please give me some guide on how to modify the code to handle and setup FreeRTOS interrupt from the PL. Thank you!

rtel wrote on Friday, July 22, 2016:

Using FreeRTOS on a Cortex-A9 is documented on the following page:
http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html

You will also find several working examples in the Zynq demos contained
in the FreeRTOS download: http://www.freertos.org/a00090.html#XILINX

how5877 wrote on Friday, July 22, 2016:

it gives the examples of internal interrupt. I would like to connect the PL interrupt pin to the freertos. I follow some of the guide here:
http://www.xuebuyuan.com/2056451.html
and
https://forums.xilinx.com/t5/Embedded-Development-Tools/PL-PS-Interrupt-for-Zynq-running-FreeRTOS/td-p/487570
both of them suggest that I need to use the prvGetInterruptControllerInstance() function, but when I do that, the compiler said it was not found. I am using FreeRTOS 9.0.0
Thank you!

rtel wrote on Friday, July 22, 2016:

I suspect prvGetInterruptControllerInstance() is used when FreeRTOS is
built as part of the BSP rather than part of the application. If you
are building FreeRTOS as part of the application then the interrupt
controller instance is just a variable you will find within the
application files. Probably the variable called xInterruptController on
line 186 of this file:
https://sourceforge.net/p/freertos/code/HEAD/tree/trunk/FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo/src/main.c

how5877 wrote on Friday, July 22, 2016:

ya, from what they did is such:

 /* Get interrupt controller instance pointer from FreeRTOS */
    GicInstancePtr = (XScuGic*)prvGetInterruptControllerInstance();

where the GICInstancePtr is the xInterruptController in the main.c you just sent me. I think the prvGetInterruptControllerInstance() function return some pointer that link the freertos interrupt with the arm interrupt. But I am not sure why when I wrote that code, it seems to not recognize.