xTaskNotifyGive issue – basic usage

Hi guys, I am trying to implement example from 9.3 chapter from Mastering The FreeRTOS Real-Time Kernel book. I am using ZYNQ-7000. Now, since I didn’t check how to simulate software interrupts on Zynq, I just decided to simply call a function from which I will call xTaskNotifyGive. This is just an illustration example. This is what I have: ~~~ int main( void ) { time_t xTimeNow;
xil_printf( "Hello world!nr" );

time( &xTimeNow );
prvSRand( (uint32_t)xTimeNow );

vPortInstallFreeRTOSVectorTable( );

Xil_DCacheEnable( );

xTaskCreate( vPlaybackTask, "Playback", 1024, NULL, configMAX_PRIORITIES - 4, NULL );
xTaskCreate( vPeriodicTask, "Periodic", 1024, NULL, configMAX_PRIORITIES - 6, NULL );

/* Start the RTOS scheduler. */
xil_printf( "vTaskStartSchedulern" );
vTaskStartScheduler( );

return 0;
} static void vExampleInterruptServiceRoutine( void ) { xTaskNotifyGive( vPlaybackTask ); } static void vPeriodicTask( void *pvParameters ) { while( 1 ) { vTaskDelay( xInterruptFrequency ); xil_printf(“Periodic task – About to generate / simulate an interrupt!n”); vExampleInterruptServiceRoutine(); xil_printf(“Periodic task – Interrupt generated!n”); } } static void vPlaybackTask( void *pvParameters ) { const TickType_t xMaxExpectedBlockTime = xInterruptFrequency + pdMS_TO_TICKS( 10 ); uint32_t ulEventsToProcess = 0;
while( 1 )
{
    ulEventsToProcess  = ulTaskNotifyTake( pdTRUE, xMaxExpectedBlockTime  );
    if( ulEventsToProcess != 0 )
    {
        while( ulEventsToProcess > 0 )
        {
            xil_printf( "Playback task -> processing -> run DMA.n" );
            ulEventsToProcess--;
        }
    }
}
} ~~~ however, ulTaskNotifyTake never returns a value different from 0. I have also checked that xTaskNotifyGive() is actually called. Maybe I am missing something obvious here? Best regards, Nenad P.S. The same example from Chapter 6.4 which uses binary semaphore instead of Task Notify is working as expected.

xTaskNotifyGive issue – basic usage

I think this recent thread: https://sourceforge.net/p/freertos/discussion/382005/thread/543fb83e/ showed xilprintf() may not be thread safe and may cause problems (which is why we normally serialse logging by only calling printf() form a single task) so in this case it might be that xilprintf() is taking longer to execute than you are allowing with the allowable margin you have set using pdMSTOTICKS( 10 ). Try increasing to pdMSTOTICKS( 1000 ) as a sanity check.

xTaskNotifyGive issue – basic usage

Hi Richard, yes, I remember the xilprintf() issue, however, since this example worked with binary semaphore, I was thinking that something else is problem. I forgot to mention that I already tried to set to portMAXDELAY, but ulTaskNotifyTake() never returned. I will examine xil_printf() again. Thanks.

xTaskNotifyGive issue – basic usage

Ah – I see the problem. The parameter to xTaskNotifyGive() is supposed to be the handle of the task the notification is sent to. The parameter you are passing is a pointer to the function that implements the task, not the task’s handle. The last parameter in your call to: xTaskCreate( vPlaybackTask, “Playback”, 1024, NULL, configMAX_PRIORITIES – 4, NULL ); is null so you never save the task’s handle. Do something like this: // File scope static TaskHandle_t PlaybackHandle; // Update call to xTaskCreate to save the handle. xTaskCreate( vPlaybackTask, “Playback”, 1024, NULL, configMAX_PRIORITIES – 4, &PlaybackHandle ); // Update call to xTaskNotifyGive() to use the handle. xTaskNotifyGive( PlaybackHandle );

xTaskNotifyGive issue – basic usage

Yes, that was a problem. I knew I was missing something obvious. But, I also thought some assert would fail if something like this happens. All in all, thank you very much for your help!