xTaskNotifyGive() and suspended tasks

rjc101 wrote on Thursday, July 13, 2017:

If I have a task suspended on a ulTaskNotifyTake with the delay set to portMAX_DELAY, I believe this is treated as a suspened rather than blocked task. Is this the same state as a vTaskSuspend and if so could a xTaskNotifyGive() wake up a task that has been explicitly suspended with a vTaskSuspend()?

i.e. is a task explicitly suspended with vTaskSuspend able to be woken up with anything other than a vTaskResume ?

rtel wrote on Thursday, July 13, 2017:

Internally, within FreeRTOS, a task that is block indefinitely is stored
in the Suspended list - but it is NOT in the Suspended state - it is
just an internal implementation. A task that is suspended using
vTaskSuspend() can only be resumed using vTaskResume(). A task that is
in the Blocked state, be it blocked on a notification or any other
primitive, cannot be resumed using vTaskResume().

rjc101 wrote on Thursday, July 13, 2017:

Hmm, that is what I presumed should be happening but if I suspend a task that was probably already blocked by the ulTaskNofityTake if I send it a notification from xTaskNofityGivefromISR it seems to wake up again. Does the order matter, i.e. the TaskNotifyTake would be before it was suspended?

I’ll see if I can replicate things to confirm what is happening, as it caught me by surpise to see a suspended task processing some data. I’m using a PIC32MZ EF processor with FreeRTOS v9.

rjc101 wrote on Friday, July 14, 2017:

I can confirm that if I have a task suspended with a vTaskSuspend it can be resumed with a direct task notification sent to a task that has a ulNotifyTake (regardless of the delay time set) pending, providing the task was waiting for a notification before being suspended.

rtel wrote on Friday, July 14, 2017:

Looking through the checkin comments in SVN I see the following on
November 25:

“Update TaskNotify.c to test the condition where a direct to task
notification is sent to a suspended task.”

So it looks like this has already been fixed in the head revision. If
it is causing an issue you can get the head revision from the public SVN
repository in SourceForge.

rjc101 wrote on Friday, July 14, 2017:

Thanks, glad it wasn’t just me doing somthing odd. I have put a workaround in my code for the moment, but I’ll also took at the repository too.

It just took a little while to track down what was happening.

mdinn wrote on Wednesday, August 16, 2017:

Hello , I thought I’d ask regarding a similar issue where a task is block using ulTaskNotifyTake(pdTRUE, portMAX_DELAY). If you vTaskSuspend() that task and then vTaskResume() it the ulTaskNotifyTake will unblock every time. I have tried this with the Head revsion of freeRTOS on svn and it still occurs. The following code shows two tasks, the second task should block forever however a call to vTaskSuspend and vTaskResume every 2 seconds unblocks this task and toggles the pin. This is the code I use to test it:

static void first_task(void *params);
static void second_task(void *params);

static TaskHandle_t first_task_handle;
static TaskHandle_t second_task_handle;

void tasks_init(void)
{
xTaskCreate(first_task, (const char )“First”, configMINIMAL_STACK_SIZE, NULL, STDBY_TASK_PRIORITY, &first_task_handle);
xTaskCreate(second_task, (const char
)“Second”, configMINIMAL_STACK_SIZE, NULL, SENSOR_FUNC_TASKS_PRIORITY, &second_task_handle);

}

static void first_task(void *params)
{

for(;;) {
		vTaskDelay(pdMS_TO_TICKS(2000));
		vTaskSuspend(second_task_handle);
		vTaskResume(second_task_handle);
}

}

static void second_task(void *params)
{

for(;;)
{
	ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
	port_pin_toggle_output_level(PIN_PA12);
	
}

}

I’ve developed a workaround in my main code for this however if there is something I am missing that can fix the issue that would be greatly appreciated.

rtel wrote on Thursday, August 17, 2017:

I thought the head revision fixed this. Will take another look.