FreeRTOS
FreeRTOS の概要
FreeRTOS (リアルタイム オペレーティング システム) は、組み込みシステムおよびマイクロコントローラー用に設計されたオープン ソースのリアルタイム オペレーティング システム カーネルです。Richard Barry によって開発され、2003 年に最初にリリースされました。FreeRTOS は、組み込みシステムでマルチタスクを実装するために使用できる、機能が豊富なリアルタイム スケジューリングおよびタスク管理メカニズムのセットを提供します。
FreeRTOS の主な目標は、軽量で効率的でポータブルなリアルタイム オペレーティング システムを組み込みアプリケーションに提供することです。産業オートメーション、IoTデバイス、家庭用電化製品、自動車制御システム、医療機器など、さまざまな組み込みデバイスおよびアプリケーション分野で広く使用されています。
FreeRTOS の主な機能
-
リアルタイム スケジューリング: 開発者は複数のタスクを作成し、タスクの優先度に従ってリアルタイム スケジューリングを実装して、優先度の高いタスクが優先度の低いタスクよりも前に実行されるようにすることができます。
-
タスク管理: セマフォ、キュー、ミューテックス、イベント フラグ グループなどの同期プリミティブを介して、タスクの作成、削除、一時停止に加え、タスク間の通信と同期をサポートします。
-
メモリ管理: メモリ管理機能を提供し、アプリケーションの要件に応じて静的メモリ割り当てまたは動的メモリ割り当てを選択できます。
-
ソフトウェア タイマー: アプリケーションが定期的または 1 回限りのタイミング機能を実装できるようにするソフトウェア タイマーが含まれています。
-
低電力サポート: Hit-Tick スリープ モードをサポートします。これにより、アイドル時にマイクロコントローラーが低電力状態になり、エネルギーを節約できます。
-
移植性: FreeRTOS は移植性が高くなるように設計されており、複数のプロセッサ アーキテクチャと開発ツールチェーンをサポートしています。
FreeRTOS を使用すると、開発者は複雑なリアルタイム タスク処理を実装でき、組み込みシステムが複数のタスクを効率的かつ確実に実行できるようになります。FreeRTOS は、そのシンプルさ、移植性、オープンソースの性質により、組み込み開発で最も人気のあるリアルタイム オペレーティング システム カーネルの 1 つとなっています。
FreeRTOS を使用する場合
-
マルチタスク: STM32 アプリケーションが複数のタスクを同時に実行する必要があり、これらのタスクをリアルタイムでスケジュールおよび管理する必要がある場合は、FreeRTOS を使用するのが良い選択です。FreeRTOS では、単一の STM32 マイクロコントローラー上で複数のタスクを作成でき、タスクの優先順位に従ってリアルタイム スケジューリングが実行され、優先順位の高いタスクが時間内に実行されることが保証されます。
-
タスク間通信と同期: メッセージの受け渡しやデータの共有など、アプリケーション内の異なるタスクが相互に通信および同期する必要がある場合、FreeRTOS によって提供される同期プリミティブ (キュー、セマフォ、ミューテックスなど) が使用されます。これらの機能は簡単に実装できます。
-
リアルタイム要件: 一部のアプリケーション シナリオには高度なリアルタイム要件があり、タスクは厳しい時間制約の下で実行する必要があります。FreeRTOS は、これらのリアルタイム要件を満たす信頼性の高いタスク スケジューリングと応答メカニズムを提供できるリアルタイム オペレーティング システムです。
-
省エネと低消費電力: FreeRTOS は Hit-Tick Sleep モードをサポートしており、アイドル時にマイクロコントローラーが低電力状態に入り、エネルギーを節約できます。アプリケーションを低電力モードで実行する必要がある場合、FreeRTOS がそれを支援します。
-
複雑なタスク処理: 複雑なタスク処理、マルチスレッド制御、またはステート マシンを含むアプリケーションの場合、FreeRTOS を使用すると、コード構造がより適切に編成され、コードの可読性と保守性が向上します。
-
クロスプラットフォームの移植性: アプリケーションを異なるハードウェア プラットフォームで実行する必要がある場合、FreeRTOS は移植性の高い機能を提供し、アプリケーション コードの移植と再利用が容易になります。
STM32 アプリケーションがマルチタスク、タスク間通信と同期、リアルタイム保証、または省エネおよび低電力機能を必要とする場合、FreeRTOS は考慮すべき非常に適切な選択肢です。ただし、各アプリケーションの要件は異なることに注意してください。単純なアプリケーションやリソースに制約のあるシナリオの場合は、他の軽量タスク管理ソリューションを選択したり、単純なポーリング コードを記述して機能を実装したりすることもできます。
STM32CubeMX で FreeRTOS を使用する方法
STM32CubeMX で FreeRTOS を使用するのは非常に簡単です。STM32CubeMX は、STMicroelectronics が提供するグラフィカル構成ツールで、STM32 マイクロコントローラの初期化コードと構成を迅速に生成するために使用されます。STM32 プロジェクトへの FreeRTOS の統合をサポートしているため、FreeRTOS タスクの作成と管理が容易になり、リアルタイム スケジューリング機能を活用できます。
STM32CubeMX で FreeRTOS を使用する基本的な手順は次のとおりです。
-
STM32CubeMX を開く: まず、STM32CubeMX ツールを開き、STM32 マイクロコントローラー モデルを選択します。
-
システム クロックとペリフェラルを構成する: プロジェクトの要件に従って、[構成] タブでシステム クロックとペリフェラルを構成します。これには、クロック ソース、クロック周波数、GPIO ピン、周辺モジュールなどの構成が含まれます。
-
FreeRTOS の構成: [ミドルウェア] タブで、[FreeRTOS] を選択して有効にします。FreeRTOS のスタック サイズやタスクの優先順位などのパラメーターを構成することを選択できます。
-
タスクの追加: FreeRTOS を構成した後、[タスク] タブでタスクを追加できます。「タスクの追加」ボタンをクリックして、タスク名、スタックサイズ、優先度などの情報を入力します。
-
タスクの構成: 追加したタスクを選択した後、右側でタスクのプロパティを構成できます。タスクの優先度、スタックサイズ、タスクの実行関数(タスク関数)を指定できます。
-
コードの生成: 設定が完了したら、STM32CubeMX ツールバーの [プロジェクト] ボタンをクリックし、[コードの生成] を選択して、FreeRTOS と統合された STM32 プロジェクト コードを生成します。
-
タスク関数を記述する: STM32CubeMX で構成されたタスク関数に従って、生成されたコード内で対応するタスクの関数を見つけ、タスクの特定の実装を記述します。
-
コンパイルと書き込み: 生成されたコード プロジェクトをお気に入りの IDE (STM32CubeIDE、Keil、IAR など) で開き、コードをコンパイルして STM32 マイクロコントローラーに書き込みます。
STM32用FreeRTOS点灯
-
STM32CubeMX を開き、STM32F4 シリーズ マイクロコントローラー モデル (STM32F407VG など) を選択します。
-
システム クロックと GPIO の構成: [構成] タブで、LED の制御に使用されるシステム クロックと GPIO ピンを構成します。LED を GPIOB のピン 3 に接続するとします。
-
FreeRTOS の構成: [ミドルウェア] タブで、[FreeRTOS] を選択して有効にします。「タスク」タブでタスクを追加できます。ここでは LED を制御するタスクを追加します。
-
タスクを追加する: [タスク] タブで、[タスクを追加] ボタンをクリックします。タスクに「LEDTask」という名前を付けます。
-
タスクを設定します。追加された「LEDTask」を右クリックし、「コード生成を開く」を選択し、「タスク関数」にタスクの関数名を入力します。タスク関数に「vLEDTask」という名前を付けます。
-
コードの生成: STM32CubeMX ツールバーの「プロジェクト」ボタンをクリックし、「コードの生成」を選択してコードを生成します。
-
タスク関数を作成する: 生成されたコード内で「vLEDTask」関数を見つけて、タスクの特定の実装を作成します。
コード例 (STM32CubeF4 HAL ライブラリに基づく):
main.c ファイルに次のコードを追加します。
//提示:包含了就不用写
#include "main.h"
#include "cmsis_os.h"
// Function prototypes
void vLEDTask(void *argument);
int main(void)
{
xTaskCreate(vLEDTask, "LEDTask", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY + 1, NULL);
vTaskStartScheduler();
while (1);
}
void vLEDTask(void *argument)
{
for (;;)
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3);
vTaskDelay(pdMS_TO_TICKS(500));
}
}