Cortex A9/Zynq ISR hangs on xSemaphoreGiveFromISR

I have been trying to solve this problem for too long now. There is clearly something I don’t quite get yet. Any pointers would be helpful. I have a DMA program that runs on the Zynq without FreeRTOS, and it runs on FreeRTOS if I use a callback function from the ISR. The problem is, it can’t be a FreeRTOS task. So I followed the example in Mastering the FreeRTOS Kernel in the interrupt section and I can’t understand why the application hangs in the call to xSemaphoreGiveFromISR. There are three tasks running and the isr handler task has the highest priority ~~~

define mainHANDLETASKPRIORITY ( tskIDLE_PRIORITY + 3 )

define mainQUEUERECEIVETASKPRIORITY ( tskIDLEPRIORITY + 2 )

define mainQUEUESENDTASKPRIORITY ( tskIDLEPRIORITY + 1 )

~~~ The semaphore is defined as ~~~ static SemaphoreHandle_t xBinarySemaphore = NULL; ~~~ main is very simple ~~~ int main( void ) { prvSetupHardware(); prvSetupDMA();
xBinarySemaphore = xSemaphoreCreateBinary();

if (xBinarySemaphore != NULL )
{
    xTaskCreate (vHandleTask, "Handler", 
                            configMINIMAL_STACK_SIZE, NULL, mainHANDLE_TASK_PRIORITY, NULL);
}

/* Create the queue. */
xQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( uint32_t ) );

if( xQueue != NULL )
{
    xTaskCreate( prvQueueReceiveTask,
                "Rx",
                configMINIMAL_STACK_SIZE,
                NULL, 
                mainQUEUE_RECEIVE_TASK_PRIORITY,
                NULL );                         

    xTaskCreate( prvQueueSendTask, "TX",
                           configMINIMAL_STACK_SIZE, NULL, mainQUEUE_SEND_TASK_PRIORITY, NULL );
}
if ( (xQueue != NULL) && (xBinarySemaphore != NULL))
    vTaskStartScheduler();
}
} ~~~ The handler task, just to get it will do processing later ~~~ static void vHandleTask (void *pvParameters) { for ( ;; ) { printf(“Before Take Interrupt Handler rn”); xSemaphoreTake (xBinarySemaphore, portMAX_DELAY); printf(“Interrupt Handler rn”); } } ~~~ The interrupt service routine ~~~ static void RxIntrHandler(void *Callback) { XAxiDma_BdRing *RxRingPtr = (XAxiDma_BdRing *) Callback; u32 IrqStatus; int TimeOut;
BaseType_t xHigherPriorityTaskWoken;

IrqStatus = XAxiDma_BdRingGetIrq(RxRingPtr);
XAxiDma_BdRingAckIrq(RxRingPtr, IrqStatus);
if (!(IrqStatus & XAXIDMA_IRQ_ALL_MASK)) {
    return;
}

if ((IrqStatus & XAXIDMA_IRQ_ERROR_MASK)) {

    XAxiDma_BdRingDumpRegs(RxRingPtr);
    XAxiDma_Reset(&AxiDma);
    TimeOut = RESET_TIMEOUT_COUNTER;
    while (TimeOut) {
        if(XAxiDma_ResetIsDone(&AxiDma)) {
            break;
        }
        TimeOut -= 1;
    }
    return;
}

// The following to wake up the FreeRTOS handler task
xHigherPriorityTaskWoken = pdFALSE;
/// This print statment always happens
printf("Interrupt 1: rn");
xSemaphoreGiveFromISR(xBinarySemaphore, &xHigherPriorityTaskWoken);
/// This print statement never happens
printf("Interrupt 2: rn");
portYIELD_FROM_ISR( xHigherPriorityTaskWoken );

// If completion interrupt is asserted, call RX call back function
// to handle the processed BDs and then raise the according flag.
//if ((IrqStatus & (XAXIDMA_IRQ_DELAY_MASK | XAXIDMA_IRQ_IOC_MASK))) {
//  RxCallBack(RxRingPtr);
//}
printf("Interrupt Out: rn");
} ~~~ the output looks like ~~~ Before Take Interrupt Handler Interrupt 1: ~~~ The isr handle task is waiting for the semaphore and the isr hangs attempting to deliver it. Any help would be appreciated.

Cortex A9/Zynq ISR hangs on xSemaphoreGiveFromISR

Hi Sting, I don’t know how your printf() is implemented, but the standard implementation is normally not interrupt-proof. I would try to debug it by setting some volatile variables and log those from a normal task.

Cortex A9/Zynq ISR hangs on xSemaphoreGiveFromISR

It hangs when I comment out the printf statements. It doesn’t hang with the printf statements when I use the callback. The only time it hangs is when I use the BinarySemaphore to wake up the handler. This interrupt is an AXI interrupt generated by the logic in the fpga. Maybe the handling has to be different. The handling of memory has to be different for the buffer descriptors because the interconnects in the fpga address memory fro 0x100000 to 0x1FFFFF. Since the callback mechanism seems to work I will temporarily move the wakeup of the handler to the callback routine so I can handle the data management in a task until I figure out how to debug this.

Cortex A9/Zynq ISR hangs on xSemaphoreGiveFromISR

I would agree with Hein, calling printf() from an interrupt is going to cause more problems that it solves. I would suggest placing a breakpoint on the xSemaphoreGiveFromISR() call and stepping through the code to see what it does, how far it gets, etc. The Cortex-A port has specific requirements for how interrupts are installed. Are you using the FreeRTOS interrupt handler, and installing the interrupts as described on the following page: http://www.freertos.org/Using-FreeRTOS-on-Cortex-A-Embedded-Processors.html Regards.

Cortex A9/Zynq ISR hangs on xSemaphoreGiveFromISR

I got the board late last night and found the problem. I do wonder why it works bare metal, but I did have a defect. ~~~ //defined in FreeRTOSConfig.h

define configMAXAPICALLINTERRUPTPRIORITY 18

// Setting the interrupt priority XScuGicSetPriorityTriggerType(&xInterruptController, XFERINTRID, 0x10, 0x3); // Should have been XScuGicSetPriorityTriggerType(&xInterruptController, XFERINTRID, 0xA0, 0x3); ~~~

Cortex A9/Zynq ISR hangs on xSemaphoreGiveFromISR

I just reread the post and: Are you using the FreeRTOS interrupt handler? I have to answer this question with a NO! Not that I wouldn’t, I just can’t find the reference to a call that would, and I looked at ~~~ void vApplicationIRQHandler( uint32t ulICCIAR ); ~~~ in FreeRTOStick_config and it looks to call the functions from the XScuGic interrupt table so I figured that just registering them was all I needed to do.