【サンプルあり】STM32のFreeRTOSの使い方まとめ

STM32CubeIDEで簡単にFreeRTOSの初期化コードを生成できますが、その先のFreeRTOSの使い方に関して情報がまだ多くありません。本記事で基礎的な内容からサンプルコードまでわかりやすく解説していきます。

STM32のFreeRTOSとは

STM32でリアルタイムOSを使いたい場合、STM32CubeIDEに入っているFreeRTOSが使用できます。STM32CubeIDEとFreeRTOSがそもそもわからない、という方は下記の記事・URLをご参照ください。

 

【基礎から導入まで】STM32CubeIDE

外部リンク:AmazonのFreeRTOS公式ガイド

 

このFreeRTOSですが、実は独特なところがあり使いこなすのが難しいと思います。理由は2つあって、順番に説明していきますね。

 

  • APIがCMSIS RTOS
  • 独自のCMSIS RTOS

 

APIがCMSIS RTOS

1つ目は、APIがFreeRTOSではなく、CMSIS RTOSベースであることです。

CMSIS RTOSとは、FreeRTOSなどのリアルタイムOSのラッパーAPIです。これを使うことで異なったOSでも共通のインタフェースで操作できるようになります。

CMSIS RTOSのバージョンはv1とv2の2つがありますが、ここではv1を前提に話を進めます。というのも、v2はコード自動生成の部分や、v2の実装自体にも問題があり、まだ安定していないためです。(2019年5月現在)

 

CMSIS RTOSのイメージ

 

例えばタスクを生成する際のAPIは、FreeRTOSとCMSIS RTOSで次のように異なります。

 

FreeRTOS

xTaskCreate(...)

 

CMSIS RTOS

osThreadCreate(...)

 

FreeRTOSに使い慣れた人からすると、新しいAPIの使い方を覚える必要があるため、腰が重く感じることでしょう。しかし、APIドキュメントが公開されているので、この点はまだ大きな問題ではありません。

 

https://www.keil.com/pack/doc/CMSIS/RTOS/html/index.html

 

独自のCMSIS RTOS

2つ目が話をややこしくしている張本人です。先ほどAPIはCMSIS RTOSと説明したのですが、STM32の実装はCMSIS RTOSそのままではありません。そのため、APIドキュメントを参考にプログラムを作っても思った通りに動いてくれないのです。

例えば、Semaphoreを取得する時ですが、API上は次のように定義されています。

 

Returns
number of available tokens, or -1 in case of incorrect parameters.

引用:CMSIS RTOS v1 Semaphores osSemaphoreWait

 

Semaphoreを取得できた時は残っているリソースの数が返され、失敗した時は-1が返されるとあります。しかし、実装はどうなっているかというと、次のようになっています。

 

int32_t osSemaphoreWait (osSemaphoreId semaphore_id, uint32_t millisec)
{
  ...
  if (semaphore_id == NULL) {
    return osErrorParameter;
  }
  ...
  else if (xSemaphoreTake(semaphore_id, ticks) != pdTRUE) {
    return osErrorOS;
  }
  
  return osOK;
}

 

簡単に説明すると、Semaphoreを取得できた時はosOKを返し、取得できなかった時はosErrorParameterやosErrorOSを返す、という実装になっています。osOKは0、osErrorParameterは128、osErrorOSは255なので、APIドキュメントの仕様を期待してプログラムを作ると、うまく動作しません。

 

どうしてこのような実装になっているか確実なことは言えませんが、意図したものであるように感じています。一通りソースコードを見渡したところ、CMSIS RTOS v1をベースにしつつ、v2の内容と独自仕様を一部取り込んだ実装になっていました。v1では不十分な所やスマートでない所もあるので、あえてそうしているように思います。

 

STM32のCMSIS RTOS v1

 

そういう意味では準拠でないのは良い面もあります。CMSIS RTOS v1から追加されているAPIを下記に並べました。関数の名前からして使えそうなものがありますよね。

 

void osSystickHandler(void);
osThreadState osThreadGetState(osThreadId thread_id);
osStatus osThreadIsSuspended(osThreadId thread_id);
osStatus osThreadSuspend (osThreadId thread_id);
osStatus osThreadResume (osThreadId thread_id);
osStatus osThreadSuspendAll (void);
osStatus osThreadResumeAll (void);
osStatus osDelayUntil (uint32_t *PreviousWakeTime, uint32_t millisec);
osStatus osAbortDelay(osThreadId thread_id);
osStatus osThreadList (uint8_t *buffer);
osEvent osMessagePeek (osMessageQId queue_id, uint32_t millisec);
uint32_t osMessageWaiting(osMessageQId queue_id);
uint32_t osMessageAvailableSpace(osMessageQId queue_id);
osStatus osMessageDelete (osMessageQId queue_id);
osMutexId osRecursiveMutexCreate (const osMutexDef_t *mutex_def);
osStatus osRecursiveMutexRelease (osMutexId mutex_id);
osStatus osRecursiveMutexWait (osMutexId mutex_id, uint32_t millisec);
uint32_t osSemaphoreGetCount(osSemaphoreId semaphore_id);

 

STM32のFreeRTOSの使い方 – 基本編

ちょっと独特なSTM32のFreeRTOSですが、使い方さえ理解すれば、十分に使えるものです。ここからは具体的な使い方の説明に入っていきますね。

 

前提条件

これ以降は下記の前提条件で話を進めます。

 

開発環境:STM32CubeIDE ver.1.00
使用するAPI:CMSIS RTOS v1(STM32仕様)
ボード:NUCLEO-F401RE

 

 

FreeRTOSの有効化

Device Configuration Tool(STM32CubeMX)を開いて、FreeRTOSを有効化しましょう。

 

  • Pinout & Configurationタブ→Middleware→FREERTOS→Mode
  • Interfaceの箇所で『CMSIS_V1』を選択

 

FreeRTOSの有効化

 

タイムベースの変更

FreeRTOSを使う場合、タイムベースにSysTick以外を指定することが強く推奨されています。余っているタイマーを指定してあげましょう。

 

  • SYS→Timebase Sourceで任意の『TIMx』を選択してください。

 

タイムベースの設定

 

FreeRTOSの機能の使い方

各機能の使い方は、個別に記事を作成していますので、そちらをご参照ください。

 

STM32のFreeRTOSのスレッド(タスク)の使い方

STM32のFreeRTOSのメッセージキューの使い方

STM32のFreeRTOSのメールキューの使い方

STM32のFreeRTOSのバイナリセマフォの使い方

STM32のFreeRTOSのカウンティングセマフォの使い方

STM32のFreeRTOSのミューテックスの使い方

STM32のFreeRTOSの再帰的なミューテックスの使い方

STM32のFreeRTOSのタイマーの使い方

STM32のFreeRTOSのシグナルの(タスク通知)使い方

STM32のFreeRTOSのメモリープールの使い方

 

ソースコードはGitHubで公開していますので、ご自由にお使いください。

ソースコード:https://github.com/yuksblog/stm32_freertos

 

STM32のFreeRTOSの使い方 – 応用編

基礎編だけでもある程度アプリケーションを作ることはできると思いますが、さらに使いこなしたいとお考えの方は、直接ソースコードを除いてみてください。下記の2つのファイルから辿れます。

 

Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h
Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.c

 

cmsis_os.hで機能リストを確認し、cmsis_os.cで実際の挙動を確認しましょう。特に実際の挙動は、CMSIS RTOSの仕様と異なる場合があるので、十分に注意してください。