Using xTaskNotify from a timer callback

Hi you all!
I’m pretty new for FreeRTOS (and embedded programming in general) so bear with me please :slight_smile:

I’m using FreeRTOS V10 on STM32F03xxx, installed from STM32CubeMx.

I’m currently running 1 periodic task that is waiting for a queue feed to get unblocked.
A software timer callback is sending an enumerated value to the queue every pre-defined amount of time.

I wonder whether changing the notification method to xTaskNotifyWait, instead of QueueReceive will save me on RAM, and if so, how to implement it?
I’ve tried to simply call xTaskNotify in the timer’s callback and check that xTaskNotifyWait is equal to pdPASS to perform the task, but it doesn’t seems to work for me.

Any suggestions?

A snippet of my code:

void appFsmTimerCallback()
{
//	appReqQueueEntry_T QueueEntry;
//	// Clear the queue entry
//	memset(&QueueEntry, 0, sizeof(appReqQueueEntry_T));
//	// Set Timeout Request
//	QueueEntry.AppRequestType = APP_CMD_TIMEOUT;
//	// Queue the TIMEOUT request to indicate timeout
//	xQueueSend(appReqQ, &QueueEntry, 10);

	xTaskNotify(appTaskHandler, NULL, eNoAction);
}

portTASK_FUNCTION(appTask, pvParameters)
{
	appReqQueueEntry_T QueueEntry;

while(1)
{
	apptasktimer=xTaskGetTickCount();

// 	if (xQueueReceive(appReqQ, &QueueEntry, 50) == pdTRUE)
 	if (xTaskNotifyWait(0, 0, NULL, portMAX_DELAY) == pdPASS)
	{
 		QueueEntry.AppRequestType == APP_CMD_TIMEOUT;
		switch(appState)
		{
                     // My FSM code comes here
                 }
         }
}
}

I have a separated function for task initialization:

ReturnCode_T appInit()
{
	// CReate the APP FSM task
	xTaskCreate(&appTask, "app", 100, NULL, 1, ( TaskHandle_t * ) &appTaskHandler);
	// Create APP FSM input queue  queue
	appReqQ = xQueueCreate(2, sizeof(appReqQueueEntry_T *));
	appTimerHandler = xTimerCreate("AppTimer", pdMS_TO_TICKS(100), pdTRUE, 0, appFsmTimerCallback);
	xTimerStart(appTimerHandler, 10);
}

and the typedef enum (for the “full picture”):

typedef enum{
	APP_CMD_START,
	APP_CMD_ABORT,
	APP_CMD_TIMEOUT,
	APP_CMD_ISR_COMPLETED
} AppReq_T;

Hope to found an answer here.
Thank you very much in advance!

If you want to send a CMD value try the light weight mailbox use case of notifications.
Use eSetValueWithOverwrite when setting the CMD value in the timer callback by xTaskNotify, provide a CMD variable (by pointer) to xTaskNotifyWait setting ulBitsToClearOnExit to ULONG_MAX (0xFFFFFFFF) and you should be fine.

That will be ideal but didn’t work as well - for some reason, the enum value that I’m trying to send isn’t being sent, therefore I’ve tried to just notify the task from the timer’s callback, without sending a value, and it didn’t work.

Is it even possible to notify a task from a timer callback?

Ok, Ok, I succeed to get it to work by sending a value of a defined value (defined in the header file) instead of a typedef enum.

But it looks like there’s no saving in RAM resources at all… Isn’t TaskNotify less demanding in resources than queue?

Sure. Your approach is perfectly right ! The mechanism I tried to explain works, too.
So the question is WHAT doesn’t work exactly ?

I’m unsure what the difference between an enumerated value and a literal (defined) value could be :thinking: In the end the notification value is a 32 bit value…
And yes, task notifications are faster and usually consume less resources.
When comparing the mailbox use case with using a queue with depth/size 1 the difference is probably not much.

I’m not sure about the difference as well. It might be something else I did wrong…
Anyway, I have worked around it with a literal value, for now, so I will keep it at the moment and come back to it later.

Thanks for your help!!