Timer: Not Pre- empting the running task

saadsaeed wrote on Monday, October 01, 2018:


I have a problem.
I have created a timer that will be called after 500 ms. It will than change a struct field to 2. By default the field is zero. After creation of timer, a while loops starts to run, that checks whether the fileld value has been changed. It should also be noted that the structure is global . Problem is that I am stucked in that while loop and it keeps on running. The task in which the while loop is working has priority 4, the priority of the timer task is 5. I am using Pre-emptive scheduling without time slicing. Basically, the timer call back function is not being called, when I am in the while loop. As soon as I delete the while loop,the timer call back function works fine.

Any suggestions would be appreciated.

rtel wrote on Monday, October 01, 2018:

It does sound like a priority issue. I know you have said the priorities should be ok, as per the values in your post, but can you double check - perhaps use a FreeRTOS aware IDE plug in to view the task priorities, or just question then from within the while loop using uxTaskGetSystemState() https://www.freertos.org/uxTaskGetSystemState.html. Can you also check that the value of the tick count is changing while you are in the while loop to discount the possibility that you have entered the loop from a critical section, or any other condition that would prevent the tick incrementing.

richard_damon wrote on Monday, October 01, 2018:

Having a task spin waiting on a value to change is not the normal way to do things with an RTOS, and is prone to having the compiler generate incorrect code. One issue is that if in the loop the compiler can’t see a way that the value might change, it might keep the value in a register and not reload it. Something like

/* Global */
int flag;

then in a f unction:

flag = 1;
while(flag) { continue; }

can generate that sort of issue. Once flag has been loaded, the compiler see no reason to go back and get a new value as it ‘knows’ what the value is.

One solution is to make the variable volatile, so the compiler needs to fetch the value new each time it is used.

rtel wrote on Monday, October 01, 2018:

Agree completely, although in this case I think the issue is that the
infinite loop ‘appears’ to prevent the timer callback function from
executing, which it should not as, according to the post at least, the
priority of the timer service task is above the priority of the task
that is spinning in the loop.