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.