使用 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)
{
}
}
答案 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”。