FreeRTOS:osDelay vs HAL_delay

时间:2017-02-16 14:10:41

标签: c embedded stm32 freertos

使用 STM32CubeMx 创建 FreeRTOS 应用程序项目时,有两种方法可用于引入延迟,即 osDelay HAL_Delay

它们之间有什么区别,应该首选哪一个?

osDelay 代码:

/*********************** 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 代码:

/**
* @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)
  {
  }
}

4 个答案:

答案 0 :(得分:8)

HAL_Delay FreeRTOS 功能, _osDelay 是一个功能构建围绕 FreeRTOS 功能。 (acc @Clifford :)它们对于不同的目的而言是不同的开发者完全不同的功能。

osDelay CMSIS库的一部分,并在内部使用 vTaskDelay()来引入延迟,与 osDelay的输入参数不同是延迟时间(以毫秒为单位),而_vTaskDelay()的输入参数是要延迟的Ticks数。 (acc。 @Bence Kaulics :)使用此功能,操作系统将收到有关延迟的通知,操作系统会将任务状态更改为阻止该特定时间段。

HAL_Delay 是我们处理器的硬件抽象层的一部分。它主要使用轮询来引入延迟。 (acc。 @Bence Kaulics :)使用此功能,操作系统不会收到有关延迟的通知。此外,如果您不使用OS,则 HAL_Delay 是HAL库提供的默认和唯一阻塞延迟。 (acc。 @Clifford :)这是 HAL Library 的一部分,可以在没有FreeRTOS的情况下使用(或者当FreeRTOS没有运行时)

要使用FreeRTOS功能引入延迟,您可以在调度程序启动后使用vTaskDelay()vTaskDelayUntil()

(acc。 @Clifford :)
如果您希望您的应用程序具有确定性,请始终支持FreeRTOS API functino CubeMX 是来自多个来源的零件集合。

答案 1 :(得分:3)

有一项优先级最高的任务。如果您打算使用HAL_Delay来阻止任务,那么可能不会成为上下文切换,因为调度程序不会被通知该任务当前只是轮询{ {1}}循环并且实际上没有做任何有用的操作。优先级较低的任务不会运行。

另一个函数使用操作系统的while函数,我没有查看它的源代码,但可能这会通知操作系统当前任务想要被阻止一段时间,所以任务&# 39; s状态将变为阻塞,同时调度程序可以切换到较低的prio任务。

答案 2 :(得分:1)

看起来HAL_Delay()看起来不适合与RTOS一起使用,因为它是一个NULL循环延迟。如果从RTOS任务调用HAL_Delay(),则任务将继续运行,直到延迟结束。优先级较高的任务将能够运行,但较低优先级的任务将在延迟期间的任何处理时间内缺乏。这是浪费处理时间,功耗,并且可能对系统响应性有害。

另一方面,

osDelay()使用RTOS实现延迟。它告诉RTOS在延迟期到期之前无事可做,因此RTOS在此期间不会为任务分配任何处理时间。这节省了处理时间,可能节省电力,并允许较低优先级的任务在延迟期间获得处理时间。 http://www.freertos.org/FAQWhat.html#WhyUseRTOS

答案 3 :(得分:0)

HAL_Delay在stm32_HAL库中使用,包括在某些情况下在ISR中调用的函数。除了命名含义是硬件抽象层以外,使用HAL_Delay(HAL_GetTick)的计时器还需要具有最高的NVIC优先级。 (因为它可能在ISR内部被调用并且不能被阻止)从实现的角度来看,这是好是坏,在Web中有一些讨论。但是,这就是ST的方法,您可以选择是否要使用STM32_HAL。

osDelay在CMSIS层中是通过vTaskDelay实现的。其中使用systick函数作为计时器。 FreeRTOS还使用systick进行任务上下文切换。根据FreeRTOS文件。操纵杆的NVIC优先级必须最低。 (因此它不会进入ISR的中间)。

首选哪种功能取决于您的工作,优先级最高,而优先级最低(根据ST和FreeRTOS的建议)。这就是如果您使用STM32CubeMX的原因,如果您选择使用FreeRTOS,它将要求您将系统定时器和systick分配为“ tick”。