Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FreeRTOS: osDelay vs HAL_delay

While creating FreeRTOS application project with STM32CubeMx, there are two ways you can use to introduce delay, namely osDelay and HAL_Delay.

What's the difference among them and which one should be preferred?

osDelay Code:

/*********************** Generic Wait Functions *******************************/
/**
* @brief   Wait for Timeout (Time Delay)
* @param   millisec      time delay value
* @retval  status code that indicates the execution status of the function.
*/
osStatus osDelay (uint32_t millisec)
{
#if INCLUDE_vTaskDelay
  TickType_t ticks = millisec / portTICK_PERIOD_MS;

  vTaskDelay(ticks ? ticks : 1);          /* Minimum delay = 1 tick */

  return osOK;
#else
  (void) millisec;

  return osErrorResource;
#endif
}

HAL_Delay Code:

/**
* @brief This function provides accurate delay (in milliseconds) based 
*        on variable incremented.
* @note In the default implementation , SysTick timer is the source of time base.
*       It is used to generate interrupts at regular time intervals where uwTick
*       is incremented.
* @note ThiS function is declared as __weak to be overwritten in case of other
*       implementations in user file.
* @param Delay: specifies the delay time length, in milliseconds.
* @retval None
*/
__weak void HAL_Delay(__IO uint32_t Delay)
{
  uint32_t tickstart = 0;
  tickstart = HAL_GetTick();
  while((HAL_GetTick() - tickstart) < Delay)
  {
  }
}
like image 302
ARK4579 Avatar asked Feb 16 '17 14:02

ARK4579


Video Answer


2 Answers

HAL_Delay is NOT a FreeRTOS function and _osDelay is a function built around FreeRTOS function. (acc @Clifford: ) They both are entirely different functions by different developers for different purposes.

osDelay is part of the CMSIS Library and uses vTaskDelay() internally to introduce delay with the difference that input argument of osDelay is delay time in milliseconds while the input argument of _vTaskDelay() is number of Ticks to be delayed. (acc. @Bence Kaulics:) Using this function, OS will be notified about the delay and OS will change the status of task to blocked for that particular time period.

HAL_Delay is part of the hardware abstraction layer for our processor. It basically uses polling to introduce delay. (acc. @Bence Kaulics:) Using this function, OS won't be notified about the delay. Also if you do not use OS, then HAL_Delay is the default and only blocking delay to use provided by the HAL library. (acc. @Clifford: ) This is part of HAL Library and can be used without FreeRTOS (or when FreeRTOS is not running)

To introduce Delay using FreeRTOS functions, you can use vTaskDelay() or vTaskDelayUntil() after the scheduler has started.

(acc. @Clifford: )
Always Favour FreeRTOS API function if you want your application to be deterministic.
CubeMX is a collection of parts from multiple sources.

like image 176
ARK4579 Avatar answered Sep 19 '22 04:09

ARK4579


It does not look like HAL_Delay() is intended for use with an RTOS because it is a NULL loop delay. If you call HAL_Delay() from an RTOS task then the task will continue to run until the delay has expired. Higher priority tasks will be able to run, but lower priority tasks will be starved of any processing time during the delay period. That is a waste of processing time, power, and can be detrimental to system responsiveness.

osDelay() on the other hand effects a delay using the RTOS. It tells the RTOS that it has nothing to do until the delay period has expired, so the RTOS does not assign any processing time to the task during that period. That saves processing time, potentially saves power, and allows lower priority tasks to get processing time during the delay period. http://www.freertos.org/FAQWhat.html#WhyUseRTOS

like image 24
Richard Avatar answered Sep 21 '22 04:09

Richard