ulTaskNotifyTake slow performance?

mrbietola wrote on Thursday, September 20, 2018:

Hi, i’m using Microblaze. My freertos tick is 10ms.
I have 2 tasks. One of them send a synch to a camera every 20 ms (50 Hz rate)
The other task should be awaken by an event, so i used ulTaskNotifyTake with a timeout. Now i’m not sending this event so the timeout runs every 30 ms.
I see that in these conditions my frame rate drops from 50 Hz to 44-47 Hz in the other task.
If i remove the xTaskNotifyWait and use a vTaskDelayUntil() , the problem disappears.
I would like to know if there is an issue with TaskNotify, can i use something else?
If i change the tick period to 5 ms, i reach 48-49 Hz but it’s still wrong!

Here are some snippets:
Camera task run a 5ms, but with a counter i send the synch every 20ms

void ir_tx_rx_task(void *pvParameters)
{
	TickType_t xNextWakeTime;

	//	Initialize xNextWakeTime - this only needs to be done once.
	xNextWakeTime = xTaskGetTickCount();

	for(;;)
	{
		//	Place this task in the blocked state until it is time to run again, 5 ms
		vTaskDelayUntil( &xNextWakeTime, IR_TX_PERIOD_MS );
		//

		ir.counter++;
        if(ir.counter==4 || ir.counter==8){
            send_synch();
		}
        if(ir.counter==8){  //transmits every 40ms
			ir.counter=0;
            }
        
        }

The task with notify that causes problems, it should be notified every 20 ms, now i’m not notifing so it should run every 30 ms:

void funnel_tx_task(void *pvParameters)
{
const TickType_t xInterruptFrequency = pdMS_TO_TICKS( 20UL ); //IR Frame period
		/* xMaxExpectedBlockTime is set to be a little longer than the maximum expected time
		between events. */
		const TickType_t xMaxExpectedBlockTime = xInterruptFrequency + pdMS_TO_TICKS( 10 );
        
        for( ;; )
		{

		if( ulTaskNotifyTake( pdTRUE, xMaxExpectedBlockTime ) != 0 ) {
                    funnel_command_manager();
					funnel_put_data();
        }
        else  {//Notify not arrived in time, should run with timeout set by    xMaxExpectedBlockTime
        
        funnel_command_manager();
			funnel_put_data();
            }
    }
        

rtel wrote on Thursday, September 20, 2018:

I am not aware of any problems with the task notification - can you
please also show the code that gives the notification.

mrbietola wrote on Thursday, September 20, 2018:

For the sake of completeness, i must say that i work in debug configuration at the moment, so i haven’t any optimization. If i use release configuration it works, but i would have expected the same timing since are slow periods.
In this moment there is nothing that sends notification, so it gets notified with xMaxExpectedBlockTime period that is 30ms. If i remove the notify and use the vTaskDelayUntil, everything works as expected, this is the only modification at the code.
Do you suggest an alternative to task notification?
I need to resume this task with a reception of a signal that arrives every 20ms

In this way it works, but the task is not dependent on the received signal anymore:

void funnel_tx_task(void *pvParameters)
{

TickType_t xNextWakeTime;

	//	Initialize xNextWakeTime - this only needs to be done once.
	xNextWakeTime = xTaskGetTickCount();

	for(;;)
	{
		//	Place this task in the blocked state until it is time to run again
		vTaskDelayUntil( &xNextWakeTime, 20UL );
		//
		funnel_command_manager();
		//	starts Tx packet
		funnel_put_data();
	}
    }

heinbali01 wrote on Thursday, September 20, 2018:

Aren’t you mixing up milliseconds and clock ticks?

All FreeRTOS functions that take TickType_t as a parameter expect clock ticks.

I think that your code needs this change:

-    vTaskDelayUntil( &xNextWakeTime, 20UL );
+    vTaskDelayUntil( &xNextWakeTime, pdMS_TO_TICKS( 20UL ) );

My FreeRTOS tick is 10ms.

So, blocking for 2 clockticks will actually last between 10 to 20 ms.

mrbietola wrote on Friday, September 21, 2018:

@Hein sorry that was a typo, the actual code have the pdMS_TO_TICKS( 20UL ) conversion.
The problem remains, it seems that using Notify function alters the timing (at least in debug configuration)