STM32 FreeRTOS Ver2 で複数のスレッドを動かしてみる

STM32 FreeRTOS Ver2 で複数のスレッドを動かしてみる

今回は手始めに FreeRTOS の Ver2 を使ってマルチスレッドしてみます。

投稿時の開発環境を記しておきます。

PC:Windows10 OS
IDE: STM32CubeIDE Version1.6.0
Configurator: STM32CubeMX Version6.2.1
Board: STM32Nucleo-F401RE

FreeRTOSについて

FreeRTOSと言っても、実体は Amazon FreeRTOS とは若干異なります。
CMSIS RTOSというものでFreeRTOSに皮を被せているイメージのものと考えておけば良さそうです。
STマイクロがFreeRTOSと呼んでいるので、こちらでも同じように呼ぶことにします。

2021年4月現在では CMSIS Ver1 と 2 が存在します。

これまで Ver1 のいくつかの機能をご紹介してきましたが、これからは Ver2 について見ていきたいと思います。

Ver2への移行で結構かわった印象を受けるので、使い慣れておきたいところですね。。

違いについては 詳細なAPI関数の違い をご覧になってください。

なおこちらでは試験的に動かしている程度ですので、充分検証をなさった上でお使いください。

参考サイト で調べながら動作確認していきたいと思います。

タスクとスレッド

よくわかっていないのですが、私はどちらも同じ意味でとらえています。
響き的にはスレッドの方が好みなので、スレッドの方を使っていこうと思います。

プロジェクトを作成する

IDEを起動し、File- New – STM32 Project を選択し、Target Selection ウィンドウが出たら Board Selector タブを選択し Boards List から NUCLEO-F401RE を選択し Next ボタンを押します。

Project 名に F401RtosV2Thread と入力し、Finishボタンを押します。
Initialize all peripherals with their default Mode ? と聞いてくるので Yesを押します。

RTOSを使えるように設定する

Pinout & Configuration – Categories – Middleware – FREERTOS を選択し、

Mode の Interface で CMSIS_V2 を選択します。

その下の Configuration – Tasks and Queues タブを選択し、 Addボタンを押します。

New Task のウィンドウが出るので、そのまま OKボタンを押します。

もう一度 Tasks and Queues タブを選択し、 Addボタンを押します。

これで以下のように2つのスレッドが追加されました。

タイムベースソースを変更する

Categories – System Core – SYS を選択し、SYS Mode and Configuration – Mode で

Timebase Source を Systick から TIM10 に変更しておきます。

FreeRTOSでは Systick 以外を使うことが推奨されているからです。

ビルドしてエラーがないことを確認しておきます。

ブレークポイントを貼ってみる

main.c に StartDefaultTask(), StartTask02(), StartTask03() の3つの関数がつくられます。

それぞれの osDelay(1) の部分にブレークポイントを貼って、動作させてみます。

動かすたびに、それぞれのブレークポイントで停止すれば成功です。

引数を渡してみる

デフォルトでは osThreadNew() の第2引数に NULL を渡していますが、
例えば以下のように構造体のアドレスを渡せば、スレッド側で受け取ることができます。

struct temp {
  int x;
  int y;
  uint32_t z;
};

struct temp t;

t.x = 123;
t.y = 456;
t.z = 789;

myTask03Handle = osThreadNew(StartTask03, (void*)&t, &myTask03_attributes);

void StartTask03(void *argument)
{
  /* USER CODE BEGIN StartTask03 */
  int x = 0;
  struct temp *t = (struct temp *)argument;

  if (123 == t->x)
  {
    // 
  }
  else
  {
    // 
  }
  /* Infinite loop */
  for(;;)
  {
    osDelay(1);
  }
  /* USER CODE END StartTask03 */
}

いかがでしたか?

うまく動きましたか。

お疲れさまでした。

FreeRTOS_V2カテゴリの最新記事