cancel
Showing results for 
Search instead for 
Did you mean: 

VTaskDelay does not wait what I espect

JulienD
Senior

Hello,

STM32L476.

FreeRTOS 10.3

This call:

while(1){
    vTaskDelay(pdMS_TO_TICKS(1000));
    HAL_GPIO_Toggle......     
}

should wait 1 second, toggle a pin again and again. With a single task, it looks ok:

0693W00000Y8l7fQAB.pngOn this graph the bottom pin toggles every second.

The blue bar is in fact a toggle on a pin in the IdleHook function which means that the MCU does nothing nearly all the time.

Now, if I add a second task that does some interesting job, with the same priority (1), here's the result:

0693W00000Y8l92QAB.pngThe delay function result is 1.6s instead of 1s. The 0.6 difference is equal to the sum of

the duration of all the moments the mcu is not idle.

My understanding is that:

  • as systick is the lowest priority, it is always counted, whatever what's going on other interrupts.
  • When the requested delay is elapsed, the os should switch to the delayed task at least when it is idle.

On this case, the MCU is idle most of the time but the delayed task is not executed after 1 second.

Why?

Thanks

Julien

3 REPLIES 3

You can try to use absolute time instead of relative time. vTaskDelayUntil provides such functionality: https://www.freertos.org/vtaskdelayuntil.html . You may still experience some jitter, but you should get better long term stability. One note is that the example mentions frequency, but it should be period.

FreeRTOS uses round robin scheduling (https://www.freertos.org/FAQSched.html), so it should periodically switch between same priority tasks. But you can help the scheduler a little by adding some "air" into busy tasks by adding yields or small delays in some places, such as loops.

Be aware of disabling interrupts. While interrupts are disabled the systick doesn't go off and you may miss ticks! You can try to disable only specific interrupts instead of globally disabling all, or you can use mutexes instead for critical sections

Kudo posts if you have the same problem and kudo replies if the solution works.
Click "Accept as Solution" if a reply solved your problem. If no solution was posted please answer with your own.

Hum, vTaskDelayUntil won't chane anything as the task with the delay do nothing except toggling a pin.

The task that uses cpu does printf. It don't see why printf would disable interrupts but that's

a good clue. I will check systick value to see if the waiting task is rescheduled after the right delay

value or not. If yes, it could be related to disabled interrupts.

Thanks

I've just did a test exporting systick value before and after the delay, it is 100 even if the timing is not 100ms. You might be right about disabled interrupts.