Task won't run without taskYield() called from within it?

adamneilward wrote on Tuesday, December 17, 2013:

Hi, I’m new to FreeRTOS and I am puzzled by something. I have 4 tasks, three of which are run using the vTaskDelayUntil() call to have them execute periodically (all three of these tasks works as expected). The 4th task however never gets called UNLESS I put a taskYield() inside it. All 4 tasks have the same priority.

static void task_FFT(void *pvParameters)
task_FFT_DebugCounter++; //one of the other tasks prints this value out
//taskYIELD(); //<— commenting out this call seems to prevent this task from running

Since the first 3 tasks are periodic and mostly waiting, shouldn’t all the remaining runtime be used for the task_FFT task? I have clearly misunderstood the workings of the scheduler but I’m not sure what I should be asking specifically.

Can someone please explain why task_FFT() never gets any CPU time? The counter never gets incremented, showing that the function is not being scheduled.

The other 3 tasks are run every 1000ms, 500ms and 100ms respectively and I don’t believe they are using 100% cpu between them.

davedoors wrote on Tuesday, December 17, 2013:

What is the priority of the task? If it is >0 then it should get all the time not used by your other tasks, if it is ==0 then it should share the time not used by your other tasks with the task.

Is task_FFT_DebugCounter declared volatile? If not the ++ can simply be optimized away as the value is never used.

Do you have configUSE_PREEMPTION set to 1 in FreeRTOSConfig.h?

adamneilward wrote on Wednesday, December 18, 2013:

You were right about the volatile declaration. I was using 7 for all four tasks’ priorities and configUSE_PREEMPTION is set to 1. Does seem to work correctly now without the taskYield call.

Oddly enough, even though all four tasks were using task_???_DebugCounter variables to indicate that they were all running, only the FFT task’s counter was being optimized out. In any case I’ve simply used the volatile constraint on all 4 timers now and everything is fine. I can throw in some other tasks now at different priorities to explore the system further.

The optimizer moves in mysterious ways.

Thanks for the help Dave, much appreciated.

jdurand wrote on Wednesday, December 18, 2013:

I’ve had the optimizer take out an array I was reading/writing in a function. I would have thought it would notice both reads and writes in the same place and leave it alone.

VOLATILE is becoming like LET in BASIC, use it everywhere.

adamneilward wrote on Wednesday, December 18, 2013:

To be honest, I’ve been seeing weirdness in my code ever since I started playing with this scheduling system. That is not a criticism, I simply have not become accustomed so the ways of the FreeRTOS yet. In time it will come to me I’m sure. It is certainly a different way of thinking about embedded firmware.

I’m finding it rather fascinating and educational.