2017-02-16 4652 views
4

在创建FreeRTOS操作系统与STM32CubeMx应用项目中,有两种方法可以用来引入的延迟,即osDelayHAL_DelayFreeRTOS操作系统:osDelay VS 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

很明显,从给定的代码(甚至不知道任何关于RTOS),第一个依赖于'vTaskDelay',第二个依赖于轮询。所以你应该基本研究'vTaskDelay'的实现。 –

回答

7

HAL_Delay不是一个FreeRTOS的功能和_os延迟是围绕FreeRTOS函数构建的函数。 (acc @ Clifford:)它们对于不同的目的都是由不同开发人员完全不同的功能。

osDelayCMSIS库的一部分,并使用vTaskDelay()内部引入延迟,区别在于osDelay的输入参数是毫秒的延迟时间而_vTaskDelay()的输入参数是数的蜱被推迟。 (acc。@Bence Kaulics :)使用此功能,操作系统会收到有关延迟的通知,操作系统会将该任务的状态更改为,并在该特定时间段内阻止

HAL_Delay是我们处理器的硬件抽象层的一部分。它基本上使用轮询来引入延迟。 (acc。@Bence Kaulics :)使用此功能,操作系统将不会收到有关延迟的通知。此外,如果您不使用操作系统,那么HAL_Delay是HAL库提供的默认阻塞延迟。 (ACC @Clifford。)这是HAL件库,可以在不FreeRTOS的(或当FreeRTOS操作系统没有运行)使用

介绍延迟使用FreeRTOS的功能,你可以使用后vTaskDelay()vTaskDelayUntil()调度程序已启动。

(ACC @Clifford:)
如果你希望你的applicatino是确定性总是青睐FreeRTOS的API functino。
CubeMX是来自多个来源的部件集合。

3

有一个优先级最高的任务。如果您打算使用HAL_Delay来阻止任务,那么可能不会有上下文切换,因为调度程序将不会被通知该任务当前只轮询while循环中的滴答计数器,并且实际上没有任何用处操作。具有较低优先级的任务将不会运行。

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

+0

嗯,这是有道理的。这就是为什么它们有两个,所以你可以根据你的任务需求使用它们中的任何一个 – ARK4579

+1

@ ARK4579另外,如果你不使用OS,那么'HAL_Delay'是HAL库提供的默认阻塞延迟。 –

+0

嗯,即在裸机编程的情况下。 SAHI。 – ARK4579

1

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

另一方面,osDelay()会影响使用RTOS的延迟。它告诉RTOS,在延迟时间到期之前它没有任何操作,所以RTOS在那段时间内不会给任务分配任何处理时间。这节省了处理时间,可能节省电力,并允许较低优先级的任务在延迟期间获得处理时间。 http://www.freertos.org/FAQWhat.html#WhyUseRTOS