I am creating a task using the following:
xTaskCreate(GFTask, “GF”, stackDepth, &taskParameter, GF
Inside of the task I am processing in a loop with a TaskNotifyWait:
xTaskNotifyWait(0x00, ULONGMAX, &ulInterruptStatus, portMAX
Inside of the DMA half and full conversion complete ISR:
if (xTaskGetSchedulerState() != taskSCHEDULERNOT
BaseTypet xHigherPriorityTaskWoken = pdFALSE;
TaskGetTaskHandle(), 2, eSetValueWithOverwrite, xHigherPriorityTaskWoken);
SWITCHING_ISR(xHigherPriorityTaskWoken); // force a context switch if higher priority task woken
/* Start scheduler */
When debugging I see there is a IDLE task, tmrsrv task and my “GF” task.
The issue is that the task will stop running pretty much as soon as the micro is started. It will just run the IDLE task continuously and never execute the GF task. The GF task is listed as being in pxReadyTasksLists. The idle task is priority 0, I think the tmrsvc was priority 2 and the GF task is priority 9. So how is it that FreeRTOS will execute a task with priority 0 and never execute my higher priority task which is in the ready list?
Going through the two xTaskNotify functions used above they look to be working correctly but something
in FreeRTOS is causing a context switch to the IDLE task mid-stream. Since the systick will not trigger a pendSV unless a task times out waiting and the IDLE task will not PendSV unless there are other tasks with the same priority this system will lose its state.
If I use portENDSWITCHING
ISR(pdTRUE); then this will trigger a context switch on every run of the ISR, but this shouldnt be required as the Notify function has this:
if( pxTCB->uxPriority > pxCurrentTCB->uxPriority )
/* The notified task has a priority above the currently
executing task so a yield is required. */
So if it is executing the “GF” task it should continue and if it is in the IDLE task when the ISR is run it should then switch to the “GF” task. But this is only run: if( eOriginalNotifyState == eWaitingNotification )
When FreeRTOS is failing it is stuck in the eNotified state since the GF task never runs.
Shouldnt FreeRTOS be designed in such a way that this kind of issue could not happen? The above method of using Task Notifications was taken from the documentation but there is no explicit warning that the task will not always
process after being notified, there is a chance it could go to the IDLE task and get stuck there unless you force a PendSV somehow. This should not even go the idle task in the first place if there is a notification to process.
Changing the code to always PendSV in the ISR is confusing and can easily be missed by someone, especially the way the code is structured and documented.
If this is what is somehow deemed the correct operation then these functions should be changed to something like xTaskNotifyFromISRSometimes
Maybe(); to indicate that the notification may not unblock a waiting task.