What happened when I call osDelay() in IdleTask?

Hi guys,
I use cubeMx to generate an MDK project with FreeRTOS, everything is the default except I enabled the idle task.

void StartDefaultTask(void *argument)
{
  for(;;)
  {
    osDelay(200);
    HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin);
  }
}

I blink the LED at the default task, everything is OK.
But when I add osDelay() in the Idle task, the LED stops to blinky. (When I try to change osDelay() to HAL_Delay(), the program works well.)

void vApplicationIdleHook( void )
{
    while(1) {
        osDelay(10000);         // can NOT work
        //HAL_Delay(10000);     // work well
        HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFE);
    }
}

Here is the question, why the osDelay() can’t work in IdleTask?
Thanks.

It is not permitted to call vTaskDelay (osDelay maps to vTaskDelay) in idle task hook - RTOS idle task and the FreeRTOS idle task hook function.

2 Likes

The reason the Idle task can’t block, is then there might be no task ready to run, and the CPU can’t run “no code”.

One of the main purposes of the Idle task is to be there so the CPU always has some code to run, and thus, it can’t block.

Thus, functions used within the Idle Hook are not allowed to block, EVER, as that will normally mean that the CPU suddenly has no code to run.

Since HAL_Delay is just a spin wait, and doesn’t block, that would work, but means the other functions of the Idle task (cleaning up after tasks that delete themselves) will also get delayed.

Note, your IdleHook function breaks that latter operation. I would suggest you could just make you IdleHook function into an Idle Priority function if it does what you really want it to do, enter the Stop Mode every 10,000 ticks of the clock (which I sort of doubt is what you actually want to do).

2 Likes

Thanks @aggarg .
That’s really what I need!

@richard-damon
Thanks for explaining to me why the Idle task can’t be blocked.
By you, I know what I can’t do, but also why.