RA4E1 Fast Prototype BoardのFreeRTOS使い方

RA4E1 Fast Prototype BoardへFreeRTOSを適用
RA4E1 Fast Prototype BoardへFreeRTOSを適用

RAファミリ評価ボードRA4E1 Fast Prototype Board (Cortex-M33/100MHz、Flash/512KB、RAM/128KB)(以降FPB)の、スイッチS1でLED2を点灯するFreeRTOS適用例を示します。RAファミリビギナーズガイド9章記載のEK-RA6M4評価キットを使った処理内容と同じです。

e2 studio 2021-10は、Project>Change Deviceで対象MCUデバイス変更機能がありますが動作しません。そこで、ガイド掲載のEK-RA6M4を手動でRA4E1へ変更し、FPBでFreeRTOSのセマフォを利用し、S1押下げ割込みとLED2トグル点灯を同期させるFreeRTOSサンプルコードを示します。

このコードを使い、前稿よりも具体的にFPBとFlexible Software Package(以降FSP)の使い方、今回は使わないTrustZoneのメリットを示すのが、本稿の目的です。

RA4E1 Fast Prototype Board(FPB)のRTOSとTrustZone

IoT MCUをクラウド接続するには、RTOSが必要です。AWS(Amazon Web Services )接続にはFreeRTOSライブラリ、Microsoft Azure接続にはAzure RTOSライブラリの利用が前提だからです。

また、クラウド接続には、TrustZoneなどハードウェアによるセキュリティ対策も要求されますので、RTOSとTrustZoneは、IoT MCUの必須2技術です。

ハードウエアセキュリティは、開発後、簡単に追加することが困難です。今回はTrustZone未使用ですが、IoTプロトタイプ開発にTrustZone内蔵Cortex-M33を用いるのは、例え未使用でも製品セキュリティ処理の具体的検討ができるなど、IoTセキュリティを開発初期から考慮した設計となるからです。

これが使わないTrustZoneのメリットです(TrustZone使用例も、いずれ投稿予定)。

本稿は、先ずFreeRTOSをFPBへ適用します。FreeRTOS新規プロジェクト作成、API生成ツールFSP設定、FSP生成ファイルへのタスク追記の順に説明します。

Step1:FreeRTOS新規プロジェクト作成

最新版e2 studio(2021-10)の新規FreeRTOSプロジェクトは、File>New>C/C++Projectとクリックし、①~⑥の手順で作成します。

FreeRTOS新規プロジェクト作成
FreeRTOS新規プロジェクト作成

②プロジェクト名は、任意です。③Boardは、PFB-RA4E1を選択します。

④TrustZone未使用時のプロジェクトを、“Flat”と呼びます。これは、TrustZone使用時、セキュアと非セキュアの2プロジェクト並存が必要となりメモリ領域を分割することに対する、平坦なメモリ使い方に起因していると思います。

※メモリ領域分割は、PCハードディスクのパーティション分割をイメージして頂ければ判り易いでしょう。例えサイバー攻撃を受けても、物理的に侵入できないメモリ領域を作り、ここへ最重要情報やソフトウェアを保存する訳です。

⑤FreeRTOSを選択します。ベアメタル(No RTOS)とAzure RTOSも選択可能です。⑥Minimalを選択し、FinishクリックでFreeRTOS(TrustZone未使用)新規プロジェクトが完成です。

各選択肢を変えると、前稿で説明した多種類の新規プロジェクトが作成できることが解ります。

Step2:Flexible Software Package(FSP)設定

Flexible Software Package (FSP)設定
Flexible Software Package (FSP)設定

新規プロジェクト作成のFinishクリックで、FSPパースペクティブオープンを聞いてきますので、開きます。

①プロジェクトSummaryが表示されます。Stacksタブを選択、②New Stackをクリックし、External IRQ Driver on r_icuを選択します。新しい外部割込みドライバがStackに追加され、③プロパティが表示されます。

FPBのユーザスイッチS1は、P205(IRQ1)に接続済みです。そこで、③プロパティのirq0をirq1、TriggerをFalling、Digital FilteringをEnable、Callbackをexternal_irq1_callbackに変更します。

次にセマフォ追加のため、④ObjectsのNew Objectsをクリックし、Binary Semaphoreを選択します。⑤プロパティSymbolをg_s1_semaphoreに変更します。

RA4E1 Fast Prototype BoardのSW1 P205(IRQ1)の確認
RA4E1 Fast Prototype BoardのSW1 P205(IRQ1)の確認

最後に、⑥pinsタブをクリックし、ユーザスイッチS1:P205(IRQ1)とIOピン割当てをGUIで確認します。

以上でFSP設定は完了です。Generate Project Contentをクリックすると、APIや割込みコールバック関数、関連ファイルが自動生成されます。

Step3:FSP生成ファイルへタスク追記

FreeRTOSセマフォ同期処理
FreeRTOSセマフォ同期処理

FSPが生成したファイル:led_thread_entry.cに上記コードを追加します。このコードは、LED初期化と無限ループ処理から構成されます。RAビギナーズガイド掲載のirq10をirq1へ変更したLEDタスクです。

コールバック関数external_irq1_callbackは、Developer AssistanceのLED Threadを開くと一番下に割込みコールバック関数が生成済みですので、これをドラッグ&ドロップして追加します。

LEDタスク追加後、ビルドしFSBへダウンロード、デバッガ起動後、再開を2回クリックして実行中の様子が上図です。FSBのS1クリックでLED2がトグル点灯します。

FreeRTOS Queueサンプルコード

前章は、RAファミリビギナーズガイド9章のEK-RA6M4評価キットFreeRTOSセマフォサンプルコードを、RA4E1 Fast Prototype Board(FPB)へ流用したコードです。変更箇所は、irq10をirq1へ変えただけです。

FSPには、FreeRTOS Queueサンプルコード:freertos_fpb_ra4e1_epも付属しています。これら2つのサンプルコードを理解すれば、セマフォとQueueを使う基本的なFreeRTOSソフトウェア開発が可能です。

FreeRTOS待合せ手段としては、セマフォ/Queue以外にもMutexやイベントグループなどの手段もあります。弊社ではFreeRTOS基礎固めを目的として、Hardware Independent FreeRTOS Exampleを応用したセマフォ/Queue活用のFreeRTOSテンプレート化を目指しています。RA/REテンプレートもこの方針で開発する予定です。

この方針で開発したNXP版FreeRTOSアプリケーションテンプレートは、コチラから概要がダウンロード可能です。

まとめ

RA4E1 Fast Prototype Board(FPB)へ、RAファミリビギナーズガイド掲載FreeRTOSサンプルコードを流用し、ユーザスイッチS1とLED2点灯をセマフォで同期させました。

FreeRTOS新規プロジェクト作成、Flexible Software Package(FSP)設定、FSP生成ファイルへのタスク追記の具体的操作手順を示しました。

ガイド9章には、更に詳細な説明がありますので、参考になります。例えば、スイッチ割込み優先度12を利用する理由、systick優先度15が予約済みであるなどです。

TrustZoneは未使用ですが、プロトタイプ開発初期からIoTセキュリティを考慮した設計ができるメリットがあります。

FSP付属Queueサンプルコードと本セマフォコードを使ってFreeRTOS基礎固め目的のRA/REテンプレート開発を進めます。

多様化MCU RTOS対策

IoT MCUクラウド市場は、AWSとMicrosoft Azureがリードしており世界収益の半分以上を占めるという記事に掲載されたのが下図です(EE Times 2021年6月7日、横軸:市場シェア、縦軸:年平均成長率)。Microsoftは徐々にAmazonに迫っており、市場シェア差は、過去1年で2ポイント縮まったそうです。

クラウトプロバイダの市場シェア(出典:記事)
クラウトプロバイダの市場シェア(出典:記事)

多様化MCU RTOS

AWSへの接続にはAmazon FreeRTOS、Microsoft AzureにはAzure RTOSを用います。IoTクラウド接続ウェビナーでは、どのMCUベンダでも先行しているAmazon FreeRTOSを使った接続例が主流です。しかし、最近は、Azure RTOS利用の接続資料やウェビナーも見られます。AWSとMicrosoft Azureの差が縮まりつつある証左でしょう。

また、第3勢力として急成長中のGoogleクラウド接続にはARM mbed OSが使われます。IoT MCUに実装するRTOSは多様化してきました。

IoT MCU RTOSとPCブラウザ

IoT MCU RTOSとPCブラウザ比較
IoT MCU RTOSとPCブラウザ比較

この状況は、PCブラウザが現状、複数共存しているのに似ています。

機能的には同じブラウザですが、表示/印刷/広告などの使い勝手が少しずつ異なるため、必要に応じて複数ブラウザを使い分ける方も多いでしょう。記憶容量の大きいPCでは、ブラウザ併用・共存も簡単です。

しかし、限られた容量しか持たないMCUの場合は、複数RTOSの中からMCU搭載RTOSは1つに絞られると思います。

例えば、AmazonやMicrosoft、Google各社の強み(販売/文書/広告)や特徴を活かし、IoT機器制御サービスやAI活用サービスなど魅力的クラウドサービスを各社各様で提供し、その価格、顧客との結びつきの強さなどがサービス選択の決め手となるでしょう。

いずれにせよ顧客が、利用するクラウドサービスを決め、その接続手段として各社RTOS接続ライブラリの使用、加えてRTOS環境での上層MCUソフトウェア開発を行うことになります。

問題は、RTOS環境のMCUソフトウェア開発手法がベアメタルと異なること、各社RTOS仕様が少しずつ異なることです。

多様化RTOS対策

仮に、Cortex-M4/M0+ディアルコアMCUで、クラウド通信処理全てを、Cortex-M0+コア側のRTOSライブラリで行い、通信とアプリケーションが完全分離された構成であれば、問題は解決します。接続サービス毎にRTOS通信ライブラリを変えさえすれば、対応できるからです。

BluetoothやThreadなど複数無線通信規格から1つを選んで処理するなど、この構成に近いベアメタルソフトウェア対応のMCUが既にあります。

しかし、主流ウェビナーで用いられる高性能Cortex-M4シングルコアを使って、クラウド通信とアプリケーションの両方を処理する場合には、接続先のクラウドに応じて「FreeRTOS/Azure RTOS/Mbed OSなど様々なRTOS環境の上層アプリケーション開発」になります。

RTOSの目的は、MCUハードウェア隠蔽と開発ソフトウェア流用性向上なのに、複数RTOS存在で開発アプリケーションが異なるとは、皮肉な結果です。

最初の図は、IoT MCU開発者が、今後急増するクラウド接続IoT MCU開発に、これら複数RTOSを効率的に習得し、かつ、顧客が選ぶ1個のRTOSアプリケーションを早期に開発できるスキルを獲得しなければならない現状や将来を示しているとも言えます。

こういう状況での常套手段は、共通部分と個別部分の分離、共通部分からの段階的習得です。

どのRTOSでもSemaphoreやQueueは、ほぼ共通の基本機能です。先ずは、この2機能をしっかり把握し、より高度なミューテックスやイベントグループなどRTOS毎に特徴があり機能も異なる対象へ発展するのが効率的でしょう。

※RTOSは、複数タスク(AzureはThread)を、優先順位に応じてリアルタイムに実行/待機/状態保存復帰の切替えを行います。タスク間同期手段がSemaphore、データ送受手段がQueueで、この2つはどのRTOSでも共通の基本機能です。

まとめ

IoT MCUクラウド市場シェアから、クラウド接続IoT MCU RTOSもPCブラウザ同様、様々な仕様併存の可能性があります。

顧客が選ぶRTOSに柔軟対応し、そのRTOS上層の様々なRTOSアプリケーションを早期開発するには、先ず、各RTOS共通機能のSemaphoreとQueueを把握し、より高度でRTOS毎に異なる個別機能へ発展する習得アプローチが効率的です。

6Eリリース予定の弊社FreeRTOSアプリケーションテンプレート(税込2000円)は、主流のAmazon FreeRTOSを用い、NXP)LPCXpresso54114(Cortex-M4/150MHz、Flash/256KB、RAM/192KB)にて動作確認済みです。

添付するRTOSプロジェクトは、各RTOS共通機能SemaphoreとQueueを利用しており、上記習得アプローチを満たすツールとして、また、全ての物をつなげる主役IoT MCU RTOS基礎固めに最適です。

FreeRTOSサンプルコード(4)

タスク数=2のMCUXpresso54114評価ボードSDK付属FreeRTOSサンプルコードの後半2プロジェクト、MutexとSemaphoreを説明します(前半は、前稿参照)。

FreeRTOSサンプルコード:タスク数=2

FreeRTOSプロジェクト:タスク数=2(後半)
Project Tasks heap_ Additional FreeRTOS APIs Additional Comments
freertos_mutex 2 4

xSemaphoreCreateMutex
xSemaphoreGive

並列動作の共有リソース同期/競合制御。taskYIELDは要注意!

Mutexのセマフォ作成は、   xSemaphoreCreateMutex。

Semaphoreのセマフォ作成は、xSemaphoreCreateBinary。

freertos_sem 1+3 4

xSemaphoreGive

※Freertos_semはタスク数4個。実質はproducer_taskとconsumer_taskの2個。

FreeRTOS Project:freertos_mutex

RTOSソフトウェアのメリットは、複数タスクが「完全に並列動作」することです。ただし、副作用として、共有リソースのアクセス競合が生じます。サンプルコードの場合はIDE Console出力で、その他にUARTやIOポートなど多くの共有リソースがMCUにはあります。

この共有リソースへのセクセス競合を防ぐ手段がミューテックスです。共有リソース使用前に他タスクの使用/未使用を検出し、未使用時のみ利用、利用後は、使用権を戻す操作(xSemaphoreGive)をします。

仮にミューテックス機能が無ければ、英字と数字が混ざった出力になり、使い物になりません。
並列動作のRTOSに、Mutexは必須機能です。

注意点は、Consoleへ部分出力後のtaskYIELDです。

F3クリックで調べましたがtaskYIELDの理由は、筆者には不明です。だだし、コメントを読むとFreeRTOSインプリメント依存部分なので、そのまま弄らない方が良さそうです。共有リソース利用中には、taskYIELDが必要と覚えておけば(とりあえず)良いとします。
※本調査の目的は、ベアメタルCortex-M4テンプレート開発へのRTOS機能応用であって、FreeRTOS自身ではないので、この程度で留めていきます👍。

共有リソース使用検出APIは、xSemaphoreTakeです。前稿freertos_ticklessプロジェクトの割込みISRと処理タスク同期に用いたAPIと同一です。差分は、セマフォ自体の作り方が異なります。ミューテックスの場合は、xSemaphoreCreateMutex、セマフォの場合は、xSemaphoreCreateBinaryです。

違いは、初期値です。ミューテックスは、初期値が使用可能(pdTRUE)になりますが、セマフォは、初期値が使用不可です。どちらも、並列動作タスク間の同期/競合制御として、同じAPI:xSemaphoreTakeを使っているということです。

FreeRTOS Project:freertos_sem

前稿freertos_ticklessで示したISRと処理タスクのセマフォ同期とは別の使用例が、freertos_ semプロジェクトです。同期というより、むしろ排他制御にセマフォを使った例です。

このプロジェクトは、これまでのサンプルコードで最も多い4タスク:1(producer_task)+3(consumer_task)を生成し、2個のセマフォ(xSemaphore_producerとxSemaphore_consumer)を使い、1個のアイテムを4タスク間で利用する例です(Doc>freertos_sem_example.txtによるとランデブーモデル同期と言うようです)。

2セマフォで1共有アイテム利用のランデブーモデル同期
2セマフォで1共有アイテム利用のランデブーモデル同期

1個の(共有)アイテムは、元々produser_taskが持っており、cunsumer_taskへその使用権を与えます(L119:xSemaphoreGive→xSemaphore_consumer)。

並列動作中の3個cumsumer_taskのどれかがこの使用権を取得します(L143:xSemaphoreTaka←xSemaphore_consumer)。使用後は、produser_taskへ使用権を返却します(L141:xSemaphoreGige→xSemaphore_producer)。

produser_taskは、cunsumer_taskの使用権返却を待っており(L121: xSemaphoreTaka←xSemaphore_producer)、返却後、再び最初に戻ってcunsumer_taskへ使用権を与えます。

cunsumer専用セマフォがxSemaphore_consumer、producer専用セマフォがxSemaphore_producerで、それぞれを図示したようにやり取りしながら4タスクが動作します。

ベアメタル風に、ランデブーモデル同期:synchronized in bilateral rendezvous modelを解説すると上記のようになります。

ソースコード上では、どのcumsumer_taskが共有アイテムを獲得するかは不明ですが、評価ボード実行結果は、常にConsumer 0→1→2→0・・・の順番でした。3個のcumsumer_taskプライオリティが同一の時は、生成順に1個のアイテム共有ができるようです。

FreeRTOSサンプルコード:タスク数=2(後半)の調査結果

  • FreeRTOSタスク並列動作副作用の共有リソースアクセス競合回避手段に、ミューテックスがある
  • MCUXpresso54114 のFreeRTOS共有リソース利用途中には、taskYIELDが必要
  • 初期値(pdTRUE)の有無が、ミューテックス作成とセマフォ作成で異なる
  • バイナリセマフォの排他制御利用例に、ランデブーモデル同期がある
  • メモリ使用法は、heap_4を利用

FreeRTOSデバイス依存開発ノウハウ

筆者のOS:Operating System利用アプリケーションソフト開発経験は、Windows PCのみです。Windows OSは、リアルタイム性はありません。そのおかげで、PCアプリケーションソフト開発時に、他タスクへの影響、プライオリティなどは考慮せずに比較的簡単に開発ができました。

ミューテックスやセマフォを利用した覚えもありません。もちろんファイルなどの共有リソースには、それなりのアクセス手順があり、それに従って開発すれば特に問題はありません。

一方MCUでOS利用の場合は、リアルタイム性は無視できません。限られたMCU能力を上手く利用するためのデバイス依存開発ノウハウが、メモリ使用法:heap_4やtaskYIELDだと思います。

これらノウハウは、ソースコード上では解りにくい代物です。また、文章記述できる量も限られます。

これには、評価ボード上でソースコードのパラメタを変えた時の挙動変化を開発者自身がつかんで習得する方法が効率的です。LPCXpresso54114(Cortex-M4/M0+ 100MHz、256KB Flash、192KB RAM)評価ボードは、入手性もよく低価格(約3400円)です。無償LPCXpresso IDEとともにご利用いただければ、本稿やFreeRTOSがより解り易くなります。

PS:FreeRTOSの最新版V10.3.0が2020年2月7日に公開されました。詳細は、リリースノートをご覧ください。

FreeRTOSサンプルコード(3)

タスク数=1の前稿FreeRTOSサンプルコード(2)に続き、本稿は、タスク数=2のMCUXpresso54114評価ボードSDK付属FreeRTOSサンプルコードの前半3プロジェクトを説明します。

FreeRTOSサンプルコード:タスク数=2

FreeRTOSプロジェクト:タスク数=2(前半)
Project Tasks heap_ Additional FreeRTOS APIs Additional Comments
freertos_tickless 2 4

vTaskDelay
xTaskGetTickCount
xSemaphoreCreateBinary
xSemaphoreGiveFromISR
xSemaphoreTake

FreeRTOS低電力動作とSW_taskの2タスク並列動作説明。

Tickless_taskは、vTaskDelay、前稿hello_taskは、vTaskSuspend。

SW_taskは、Tickless_taskに何ら影響を与えない。

freertos_i2c 2 4

xSemaphoreCreateBinary
xSemaphoreGiveFromISR
xSemaphoreTake

master_taskとslave_taskの2タスク構成。正常動作結果は、Console窓出力。DoC>readme.txtでも結果が判る。

freertos_spi 2 4

xSemaphoreCreateBinary
xSemaphoreGiveFromISR
xSemaphoreTake

同上

タスク数=2のサンプルコードは、上記以外にもFreeRTOS特徴のミューテックスとセマフォ利用例がありますが、これらは次回説明します。

FreeRTOS Project:freertos_ tickles

前稿説明のhello_taskは、Console窓に文字を1回出力し、「待ち状態」になりました。
hello_task とよく似たTickless_taskは、文字の代わりにxTaskGetTickCountで得た数字を1回出力し、vTaskDelayで5秒間の「停止状態(=低電力動作:Sleep)」になります。

低電力動作からの復帰Eventで、Tickless_taskは停止状態から実行可能状態へ移行し、スケジューラによって再実行されます。停止時間5秒間のtick回数がConsole窓に出力されます。
※FreeRTOSタスクの状態遷移図は、マイコンRTOS習得2017の第2部を参照。

このプロジェクトは、Tickless_task が、SW_task動作に全く影響を受けないFreeRTOSの特徴を説明しています。

つまり、Tickless_taskと、SW_taskは、それぞれ別々にあたかも自分のタスクがMCUを占有するように記述されており、かつその通り並列動作します。これがFreeRTOS利用ソフトウェア開発の最大メリットです。タスク開発は、ベアメタルソフトウェア開発に比べ簡単に、かつ流用性も大きくなるでしょう。

※SW3プッシュは、ソフトウェア、ハードウェアで何もチャタリッグ防止策をしていない処理の検証にも使えます。試しにSW3を長く押してチャタリッグが発生することを確かめてください。チャタリッグ防止策の必要性が解ります。

FreeRTOS Project:freertos_ i2cとfreertos_ spi

freertos_ i2cとfreertos_spiプロジェクトは、どちらもMCU内蔵I2C、またはSPIを使った外部デバイスとの通信サンプルコードです。どちらもmaster_taskとslave_taskの2タスクから構成されています。

main.cでslave_taskのみをタスク登録し、slave_task内でmaster_taskを登録しています。このように、FreeRTOSスケジューラ起動後でも、任意の場所で新たなタスク登録が可能です。

動作は、最初master_taskでデータ送信し、それをslave_taskで受信、次にslave_taskがデータ送信し、それをmaster_taskで受信し、両タスクとも正常終了します。

この動作シナリオは、slave_taskに記述されており、master_taskのデータ送信開始は、slave_taskのmaster_task登録の結果、並列実行されます。slave_taskのデータ受信と送信完了は、i2c_slave_callbackからのセマフォを使って判断しています。

評価ボード実装Arduinoコネクタ上の配線で、送受信データをループバック接続しますので、評価ボード1台のみで両タクス動作結果が、IDEのConsole窓に出力されます。

MCUXpresso54114評価ボードをお持ちでない方は、両プロジェクトのDoc>readme.txtのRunning the demoにConsole窓出力と同じ結果があるので解ります。

I2C/SPI通信対象のデバイスは、従来からの外付けEEPROMに加え、最近ではIoTセキュティデバイスなどがあります。

IoTセキュティデバイスは例えば、NXPのEdgeLookやMicrochipのCryptoAuthenticationファミリなどがあり、IoT MCUのクラウド接続には、これらデバイス利用が必須になりそうです。

I2C通信のIoTセキュリティデバイス接続例(出典:NXP SE050データシート)
I2C通信のIoTセキュリティデバイス接続例(出典:NXP SE050データシート)

FreeRTOSサンプルコード:タスク数=2(前半)の調査結果

  • FreeRTOS低電力動作(Sleep)は、vTaskDelay(msec)で低電力動作開始と復帰
  • タスク数が2と少ないので、タスク並列動作が解り易く、プライオリティ設定とその意味も理解容易
  • I2C/SPI割込みISRとのタスク同期に、バイナリセマフォ利用
  • 割込みcallback関数でセマフォをgive → 割込み処理タスクでセマフォをtake → セマフォ消滅
  • IoT MCUは、セキュティデバイスとのI2C接続可能性大
  • メモリ使用法は、heap_4を利用

セマフォ(Semaphore)同期は、マイコンRTOS習得2017の第3部:Semaphoreによるタスク同期の章に、図入り解説していますのでご参照ください。

FreeRTOSサンプルソースコードは、MCUXpresso IDEのみでも御覧頂けます。是非、PCへインストールし本稿をご参照ください。

RTOSへの備え:最終回、FreeRTOSサンプルソフト

FreeRTOSの要点を第1回~第3回でなるべく簡潔に解説してきました。簡潔にし過ぎて部分的には不正確な記述もあります。

しかし、正確さに拘って記述すると分(文)量が増え、参考書の和訳になりかねません。ポイントとなる点をざっと掴んで、開発環境で試し、参考書やマニュアルなどで開発者自ら考える、これにより新しい技術を本当に身に付けることができます。私は、これを食物の消化に例えます。

これには、出だしでつまずかず、多少間違えてもスムースに学習を進めること(=先ずは食べること)が大切です。食べたものの消化には、時間が掛かります。後で振り返ると、内容や詳細が解るということはよくあります。

開発者への「開発スピードを上げよ」というプレッシャーは、益々強まります。この状況で技術を身に付けるには、効率的に頭の中の整理、これこそが消化、が必須です。

最良の解説書は、「サンプルソフト+評価ボード」

ソフト開発は、つまるところ、ソースコード+評価ボードによる開発環境に勝る解説書は無いと思います。ソースコードを読み理解するのに最低限必要な知識と、実際のマイコンで使えるFreeRTOSサンプルソフトを示す、これが今回のRTOS関連記事の目的です。

そこで、第3回のタスク間データ通知、同期、排他制御の自作サンプルソースや、NXPオリジナルのLチカサンプルに、より解りやすい日本語コメントを付加した第1回のLチカサンプルソースを弊社サイトのRTOSページで公開します。

このサンプルソフトを使えば、より具体的に、日本語コメント付きソースコードを参照しながらRTOS習得や理解ができます。評価ボードで動作が即確認できますので、出だしのつまずき回避にも有効です。

FreeRTOSのAPIは、多くのパラメタを含みます。パラメタを変えた時に、どのように動作が変わるかをサンプルソースに修正を加え、評価ホードで試すことができます。これは、結構重要です。食べ方を自分で変えて消化することに相当するからです。また、このパラメタ変化を事細かに記述する術は(多分)ありません。

しかし実際の開発では、この事細かな事柄を知っていないと、トラブルやバグ回避ができません。このことが「サンプルソフト+評価ボード」が最上の解説書とする理由です。

FreeRTOSサンプルソフト

FreeRTOSサンプルソフトは、NXP製LPCXpresso824-MAXで動作します。
RTOSへの備え:第1回に予定していたLPCXpresso812/812-MAX、LPCXpresso1114/5の動作確認結果が下表です。

FreeRTOSサンプルソフト動作確認状況
FreeRTOSサンプルソフト動作確認状況

LPCXpresso824-MAXで動作するソースを使い、IO割付と使用LPCOpenライブラリのみを変更し、他評価ボードへ適用しました。LPCXpresso812は824-MAXと同様に動作しますが、LPCXpresso1114/5は、Lチカ以外の動作確認ができません。また、LPCXpresso824-MAXもMutexは、希望の動作をしません。代用として2個のセマフォを使って疑似的に実現しました(Mutex2)。MutexとLPCXpresso1114/5の動作NG原因は不明です。原因が判明しましたら、弊社サイトへ記載します。

以上のように出来が良くありませんので、LPCXpresso824-MAXのFreeRTOSサンプルソフトのみをサイトで公開いたしました。
※2020年3月、このFreeRTOSサンプルソフトをLPCXpresso54114対応へ更新し、LPCXpresso824-MAXサンプルソフトは削除しました。

当初目的の全ボードでのFreeRTOS動作確認は出来ていませんが、これも、(かなり無理があることは承知の上で)評価ボード検証のあかしと考えることにします(Orz)。

※動作しない原因がお判りの方は、info@happytech.jpへまで教えていただけると助かります。

PSoC 6続報

MONOist組み込み開発ニュースに、PSoC 6と他社製品との性能、消費電力の比較が掲載されています(出典:「業界最小」の消費電力でセキュリティも、サイプレスがIoT向け「PSoC」を投入)。

PSoC 6の目標

「ある程度のシステム制御ができる性能+低消費電力+セキュリティ、これらの同時実現」というPSoC 6の目標のために採用された40nmプロセス技術とデュアルARMコアにより、PSoC 6の他社比、優れた性能が解ります。

PSoC 6 Comparison Table1
PSoC 6 Comparison Table1(記事より)
PSoC 6 Comparison Table 2
PSoC 6 Comparison Table 2(記事より)

青字が性能同等、または、より優れた項目を示しています。PSoC 4でも採用中の高性能CapSenseやアナログコンポーネント、多くのGPIO数、そして100MHz動作のCortex-M0+、ピーク時257DMIPSなど、弊社ブログ対象の従来MCUの性能枠を大きく超えるものです。

1MB ROM、288KB RAM、8KB キャッシュの意味

ディアルコアで、1MB ROM、288KB RAM、8KB キャッシュものリソースを持つPSoC 6制御には、RTOSが必要になると思います。MCU開発も、よいよOS必須時代になるのでしょうか?

PSoC Creator News and InformationにNew FreeRTOS on PSoC 4 port が掲載されています(PSoC Creator 4.0のStart Pageからもアクセス可能)。弊社マイコンテンプレートで使ったCY8CKIT-042 評価ボードへも適用できそうです。ARMコアなので、mbed OS 5も気にはなりますが、FreeRTOSですので、RTOSへの備え記事が、理解に有効に活用できるでしょう。

弊社自作FreeRTOSサンプルソフト状況

RTOSへの備え記事は、LPCXpresso 824-MAXを使ってFreeRTOSサンプルソフトを自作しています(Lチカ、Q-通信、セマフォ同期、ミューティックス排他制御の4種)。

この自作サンプルを横展開してLPCXpresso 812/812-MAX、LPCXpresso 1114/5へ適用する予定でした。しかし、LPCXpresso 824-MAXで動作するサンプル(勿論GPIOとLPCOpenライブラリのみ変更)が、Lチカを除いて他の評価ボードでは動作確認ができないのが現状です。

原因が(僅か数十行の)自作サンプルにあるのか、それとも、それ以外かの見極めも、結構大変です。FreeRTOSもv9では、スタティックなセマフォ、ミューティックス割付ができるなど改良が進んでいるのでデバッグには良さそうですが、現状のv8は未だ非対応です。

LPCXpresso 824-MAX版だけでもFreeRTOSサンプルソフトを無償リリースするか、それとも、当初の予定どおり全評価ボード対応として問題解決後リリースするか3月末を目途に検討中です。

RTOSへの備え:第3回、タスク間データ通知、同期、排他制御

各タスクが独立=バラバラで動作する場合には、第2回に示したスケジューラーのRunningの切り替えのみでもRTOSを使ったマルチタスクとしては十分機能します。実際、LPCXpresso付属のfreertos_blinkyサンプルソフトを理解するには、第2回までの説明で十分です。

しかし、あるタスクの結果を待って別タスクが動作するような場合には、結果の待ちや通知、タスク間の同期が必要です。今回は、RTOSがどのようにこれらタスク間のデータ通知、同期を行っているかを解説します。

これらの技術を習得すれば、殆ど(7割以上)のソフト開発をFreeRTOSでカバーできるようになります。つまり、ここがRTOS習得の山場と言っても良いでしょう。少し量が多いのですが、ご勘弁を…。

初めに、状態遷移図のSuspendedによるタスク間の待ちや同期を行う仕組みを説明し、次に具体的な方法を説明します。

Suspendedの役目

第2回で示した状態遷移図のSuspendedが、タスクの待ちを実現します。

タスクAとタスクB間の通知や同期には、タスク実行中に別タスクの結果を待つことが必要となります。タスクAに待ちが発生した時は、vTaskSuspened()のAPIを使ってSuspendedへ移行し、タスクBの結果を受け取ると、RTOSがvTaskResume()のAPIを使ってタスクAをReadyへ戻します。Suspended中も第2回で示したBlocked同様、MCU能力を消費しませんので、待ち期間中も他のタスクがRunningすることができます。

以上がSuspendedによるタスクの待ちや同期を行う仕組みの簡単な説明です。Blockedと似ていることが解ると思います。違いは、BlockedがRunningからのみ遷移するのに対し、どの状態からでもSuspendedへ遷移できる点です。次にRTOSでの具体的な方法を示します。

FreeRTOSのタスク間データ通信、同期、排他制御の方法

RTOSを使わない通常ソフトの場合は、ユーザが定義するメモリ経由で、変数や結果の通知をユーザ自身が行います。また、割込みにより同期が可能です。弊社マイコンテンプレートもこの方法を使っています。

FreeRTOSを使うソフト開発の場合は、
タスク間のデータ通信は、           Queues:キュー、
タスク間の同期は、                      Semaphore:セマフォ、
タスク間の排他制御は、               Mutex(=mutual exclusion):ミューティックス、
を使います。

Queues:キューによるタスク間データ通信

FreeRTOSは、Operating SystemですのでMCU資源のユーザによる直接アクセスを嫌います。メモリなどの直接表現ではなく、論理的にメモリを繋げたQueues:キューという手段で、通信という方法によりタスク間データ送受信を行います。FreeRTOSのタスク間通信Queues:キューは、FIFO:First In First Outとして使います。

FreeRTOS Task Communication
FreeRTOS Task Communication

タスクAからタスクBへキュー経由でデータ通信する例です。受信タスクBは、xQueueReceive()でキューからのデータを受信します。このキューにデータが無い時のみSuspendedへ移行します。Suspended中は、キューデータ有無をRTOSが監視し、データが生じた時はタスクBのxQueueReceive()以降の処理が実行されます。

つまりタスクBは、xQueseReceive()の記述のみでデータ受信処理が実現できます。データ有無による待ち制御は全てRTOS側で行いますので、タスクBは受信処理のみの簡単記述ができます。

キューにより送受信タスクの処理は完全に分離されますが、処理結果のデータは、FIFOなので順序が保たれて通信されます。

Semaphore:セマフォによる同期

FreeRTOSのSemaphore:セマフォは、バイナリセマフォです。割込みによる同期を図示します。

FreeRTOS Semaphore
FreeRTOS Semaphore

割込み処理は、割込みハンドラーと割込みサービスルーティン:ISRの2つで構成します。割込み発生時、優先順位に応じてMCUハードウエアが自動的にCallするのが割込みハンドラー、実際の割込み処理を記述する部分がISRです。※図では、Interrupt!がハンドラー、TaskがISRです。

FreeRTOSの割込み同期は、ISRで割込み発生をxSemaphoreTake()で待ちます。割込み発生時、ハンドラーで割込みフラグクリアなどの処理後、xSemaphoreGiveFromISR()で動作許可(図赤丸)を与えます。この動作許可によりISRのxSemaphoreTake()以降の割り込み処理が実行されます。これが割込み同期の実現方法です。

ISR処理後、動作許可は消えます。再びハンドラーが動作許可を生成するまでISRはSuspendedになります。

Mutex:ミューティックスによる排他制御

FreeRTOSのMutex:ミューティックス排他制御を図示します。

FreeRTOS Mutex
FreeRTOS Mutex

ミューティックスの場合は、セマフォと異なり初めから動作許可(図赤丸)があります。この動作許可を初めにTakeしたタスクAのみが共有リソースへアクセスできます。タスクAのアクセス中は、動作許可がないタスクBはxSemaphoreTake()でSuspendedになります。タスクAのアクセス終了後、動作許可をxSemaphoreGive()で放棄するので、今度はタスクBが共有リソースへアクセスできます。これが排他制御の実現方法です。

つまり、動作の許可を示すバイナリセマフォを同期で使う時はセマフォ、排他制御で使う時はミューティックスと呼ぶだけで、使用するAPIは、どちらもxSemaphoreGive()とxSemaphoreTake()です。
違いは、セマフォ同期のvSemaphoreCreateBinary()では、初期値:動作許可が無いこと、ミューティックス排他制御のxSemaphoreCreateMutex()では、初期値:動作許可が有ることです。

まとめ

FreeRTOSのタスク間データ通信、同期、排他制御の方法を示しました。これら待ちの制御は、スケジューラーのタスク管理Suspendedが重要な役割を果たします。

データ通信は、Queue:キュー作成後、このキューへタスクからデータSend/Receiveという通信で実現します。同期と排他制御は、Semaphore:セマフォ作成後、このセマフォへタスクから動作許可Give/Takeにより実現します。

タスク側の記述は、データのキューSend/Receive、セマフォの動作許可Give/Takeという単純なFreeRTOSのAPIのみで良く、関係タスクの状況に応じて即Runningにするか、あるいはSuspended→Ready→Runningにするかの面倒な制御は、全てRTOS側が行います。従って、ユーザタスクは、必要処理の簡単記述ができます。

今回登場したFreeRTOSのAPIが以下です。

キューデータ通信:          xQueueCreate()、xQueueSend()、xQueueReceive()
セマフォ同期:                  xSemaphoreCreateBinary()、xSemaphoreGiveFromISR()、xSemaphoreTake()
ミューティックス排他制御:xSemaphoreCreateMutex()、xSemaphoreGive()、xSemaphoreTake()

上記と、第2回で示したFreeRTOSのAPIとを加えても20個弱のAPIでFreeRTOSが使えます。これらのAPIとFreeRTOSスケジューラーを理解していれば、FreeRTOS以外でも慌てずにRTOSソフト開発に着手できると思います。

最終回の次回は、ソースコード+評価ボードの開発環境に勝る解説書はない、という話をする予定です。