「ベアメタル」とは、OS(オペレーティングシステム)を使わず、while(1) ループの中に処理を全部書いていく開発スタイルのことです。LEDを点滅させたり、センサを1つ読み取るだけなら、これで十分シンプルに動きます。
しかし、IMU(慣性センサ)を一定間隔で読み取りながら、GNSS(衛星測位)のデータも解析し、同時に画面表示やボタン操作にも反応させたい——というように「同時にやりたいこと」が増えてくると、ベアメタルは途端に難しくなります。全部を1つのループの中で手作業で切り替えなければならず、どこか1箇所の処理に時間がかかると、他の処理がすべて止まってしまう、といった問題が起きやすいのです。
そこで役立つのがFreeRTOSのような「RTOS(リアルタイムOS)」です。RTOSを使うと、それぞれの処理を「タスク」という独立した単位に分けて、優先度をつけて実行できます。例えば「IMUの読み取りは最優先」「画面更新は後回しでもOK」といった制御を、自分でスケジューリングの仕組みを書かなくても実現できます。また「キュー」「セマフォ」「ミューテックス」といった仕組みを使うことで、タスク同士が安全にデータをやり取りできるようになり、変数の競合によるバグも防げます。
もちろんRTOSにも、メモリを多く使う・タスクの優先度設計を学ぶ必要がある、といったハードルはあります。ですが、複数の処理を同時に、かつ確実なタイミングでこなしたい組み込み開発では、それを上回るメリットがあります。
本記事では、STM32CubeIDEでFreeRTOSを導入する手順を、CubeMXでのRTOS有効化からタスク・キュー・セマフォの作成まで、順を追って解説します。
導入手順
STM32CubeIDEを起動し、iocを開きます。
「Middleware and Software Packs」の中から「FREERTOS」を選択し、「Mode」の「Interface」から「CMSIS_V2」を選択します。

次に、「Configuration」の「Advanced settings」を選択し、「Newlib setting」の中の「USE_NEWLIB_REENTRANT」をEnableにします。

次に、「System Core」から「SYS」を選択し、「Mode」の「Timebase Source」をSysTickでタイマーを選択します。今回はTIM6にします。

そのまま保存し、コードを生成します。これでOSを実装することができます。

main.cを開き、以下のようなコードが生成されていれば、導入完了です。

