STM32CubeMxを使用してFreeRTOSアプリケーションプロジェクトを作成する場合、遅延を導入するために使用できる2つの方法、つまり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)
{
}
}
HAL_Delayis[〜#〜] not [〜# 〜]aFreeRTOS関数と_ osDelayは、FreeRTOS関数を中心に構築された関数です。 (acc@ Clifford:)これらは両方とも、異なる目的のために異なる開発者によって完全に異なる機能です。
osDelayはCMSISライブラリの一部であり、vTaskDelay()内部的に遅延を導入しますが、osDelayの入力引数はミリ秒単位の遅延時間であり、_vTaskDelay()の入力引数は遅延するティックの数です。 (acc。@ Bence Kaulics:)この関数を使用すると、OSに遅延が通知され、OSはタスクのステータスをblockedその特定の期間。
HAL_Delayは、プロセッサのハードウェアアブストラクションレイヤーの一部です。基本的に、ポーリングを使用して遅延を導入します。 (acc。@ Bence Kaulics:)この関数を使用すると、OSは遅延について通知されません。また、OSを使用しない場合は、HAL_Delayがデフォルトであり、HALライブラリによって提供される使用をブロックする遅延のみです。 (acc。@ Clifford:)これはHALライブラリの一部であり、FreeRTOSなしで(またはFreeRTOSが実行されていないときに)使用できます。 )
FreeRTOS関数を使用してDelayを導入するには、スケジューラーの開始後に vTaskDelay() または vTaskDelayUntil() を使用できます。
(acc。@ Clifford:)
アプリケーションを決定論的にしたい場合は、常にFreeRTOS APIfunctinoを優先してください。
CubeMXは、複数のソースからのパーツのコレクションです。
優先度が最も高いタスクがあります。 HAL_Delay
を使用してタスクをブロックする場合、タスクが現在while
ループ内のティックカウンターをポーリングしていることをスケジューラーに通知せず、実際に行うため、コンテキストスイッチはおそらくありません。有用な操作は行いません。優先度の低いタスクは実行されません。
他の関数はOSのvTaskDelay
関数を使用します。ソースコードを覗き見しませんでしたが、おそらくこれにより、現在のタスクが一定時間ブロックされることをOSに通知するため、タスクの状態はに変わります。ブロックされたそしてスケジューラーはその間に低いprioタスクに切り替えることができます。
HAL_Delay()はNULLループ遅延であるため、RTOSでの使用を目的としているようには見えません。RTOSからHAL_Delay()を呼び出す場合タスクの場合、タスクは遅延が期限切れになるまで実行を継続します。優先度の高いタスクは実行できますが、優先度の低いタスクは遅延期間中の処理時間が不足します。これは、処理時間、電力、およびシステムの応答性に悪影響を与える可能性があります。
一方、osDelay()は、RTOSを使用して遅延を引き起こします。 RTOSは、遅延期間が終了するまで何の関係もないことを通知するため、RTOSは、その期間中のタスクに処理時間を割り当てません。 。これにより、処理時間が節約され、電力が節約される可能性があり、優先度の低いタスクが遅延期間中に処理時間を取得できるようになります。 http://www.freertos.org/FAQWhat.html#WhyUseRTOS