FreeRTOSサンプルコード(5)

MCUXpresso54114評価ボードSDK付属FreeRTOSサンプルコード調査最終回の本稿は、タスク数=3のプロジェクト、freertos_eventとfreertos_queue、freertos_genericを説明します。

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

FreeRTOSプロジェクト:タスク数=3
Project Tasks heap_ Additional FreeRTOS APIs Additional Comments
freertos_event 3 4 xEventGroupCreate xEventGroupSetBits
xEventGroupWaitBits

タスクや割込みなどのイベントをグループ化し、他タスク制御。

セマフォと似ているがイベントの論理演算可能。

freertos_queue 3 4 xQueueCreate
xQueueSend
xQueueReceive
vQueueAddToRegistry
タスク間メッセージ通信デモ。キューは、順序維持FIFO構造。
freertos_generic 3 4

キュー、ソフトウェアタイマ、セマフォの組合せデモ。

FreeRTOS.orgサンプルコードに基づき作成。

※freertos_genericのAdditional FreeRTOS APIは、これまでのサンプルAPI組合せのため追加分なし。

FreeRTOS Project:freertos_event

イベントによるタスク制御は、セマフォに似ています。複数のセマフォを1つにまとめたイベントグループを作成(xEventGroupCreate)し、このグループ化した個々のイベント間で論理演算ができることが特徴です。

xEventGroupWaitBitsの例(出典:freertos_event.c)
xEventGroupWaitBitsの例(出典:freertos_event.c)

イベント間の論理演算ができるので、シングルイベントのセマフォよりも柔軟なタスク制御ができます。

FreeRTOS Project:freertos_queue

これまで説明してきたプロジェクトのタスク間制御には、ミューテックスやセマフォ、上記イベントなど全てビット単位のシグナルを使ってきました。最後に説明するプロジェクトfreertos_queueは、タスク間でメッセージを送受信します。

メッセージは、キュー=有限長FIFO(First In First Out)経由で送受信されますので、メッセージの順番は維持されますが、キューが溢れないような使い方が必要です。深すぎるキューはメモリ効率が悪く、浅いキューではメッセージが溢れます。深さ見積もりなどのためにプロトタイプ開発が必要でしょう。

例えば、複数センサ出力をMCUでまとめ、定期的にクラウドへ送信するようなFreeRTOSアプリケーションソフトの素になりそうなプロジェクトです。クラウドサービスにAmazon Web Service(AWS)を使う時には、専用のネットワーク接続ライブラリもFreeRTOSで提供されますので、このアプリケーションとの親和性も良いと思います。

FreeRTOS Project:freertos_generic

MCUXpresso54114評価ボードSDK付属FreeRTOSサンプルコード11個の説明の最後が、このfreertos_genericプロジェクトです。これまで説明してきた10個のサンプルコードを総合的にまとめたプロジェクトで、出典はhttp://www.freertos.org/Hardware-independent-RTOS-example.htmlです。

筆者の下手な説明よりも、実際にソースコードを見て頂くと丁寧なコメント付きです。このソースコードを読んでFreeRTOSの仕組みがすんなりと理解できれば、ベアメタルからFreeRTOSソフトウェア開発へのステップアップ初期段階は完了と言えるでしょう。つまり、10個サンプルコード習得度の自己評価に使えます。

FreeRTOSサンプルコード:タスク数=3の調査結果

  • 複数セマフォを1つにまとめたイベントグループタスク制御は、イベント間の論理演算が可能
  • キュー利用のタスク間メッセージ通信は、深さ設定にプロトタイプ開発が有効
  • freertos_genericは、SDK付属サンプルコード10個の習得度評価に使える
  • メモリ使用法は、heap_4を利用

まとめ:MCUXpresso54114評価ボードSDK付属FreeRTOSサンプルコード調査

5回に渡ってMCUXpresso54114評価ボードSDK付属FreeRTOSサンプルコードをタスク数が少ない順に調査しました。基本的なFreeRTOS機能は、解説済み11個のサンプルプロジェクトでカバーされています。

各プロジェクトの追加分FreeRTOS APIのみを表で示し、しかも弊社サイトマイコンRTOS習得2017の内容は既にご存じという前提で説明したので、解りにくい部分もあったかもしれません。
要するに、ベアメタル開発にFreeRTOS APIを追加すればRTOSソフトウェア開発ができることを強調したかったからです。

FreeRTOSのマルチタスク並列動作、タスク間同期/競合回避手段、これらのFreeRTOS APIのみを理解すれば、ベアメタル開発経験がそのまま活かせます。

今回の1~5回の解説は、マイコンRTOS習得2020年版として2017年版サイトへ改版する予定です。改版後にご覧になれば解りにくさが改善されるかもしれません。

調査目的は、開発予定のベアメタルCortex-M4テンプレートへのRTOS機能応用でした。現時点で、応用内容は不明確です。しばらく時間を頂いて明確化します。

ただ、マルチタスクFreeRTOSと異なり、ベアメタルテンプレートは、全て自分の制御下タスクです。タスク間同期やメッセージ送受信も、特別な工夫なく簡単に実現できます。

FreeRTOS利用MCUのAWS接続(出典:Amazon FreeRTOSの開始方法に加筆)
FreeRTOS利用MCUのAWS接続(出典:Amazon FreeRTOSの開始方法に加筆)

上図のように、AWSへの接続やIoTセキュリティ機能追加など今後必須になるIoT MCUの機能実装は、専用ライブラリベース、特にFreeRTOSライブラリで提供される可能性が高いと予想できます。

これらライブラリは、ベアメタル開発でも利用可能ですが、FreeRTOSソフトウェアの方が親和性も高く開発が容易なことも事実です。

しかも、これら専用ライブラリで実行される処理内容は、本来我々開発者が変更を加えるべきでない定型処理です(もちろんプロパティなどのパラメタは、開発者依存です)。

いずれにしても、MCUXpresso54114を使ったFreeRTOSソフトウェア開発環境と基本機能は習得できたので、ベアメタルCortex-M4テンプレート開発へ活かしていきます。

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へインストールし本稿をご参照ください。

ARM Cortex-M4とM0+アプリケーションコード互換

NXP MCUXpresso SDK利用を利用すると、LPC845 Breakout board用に開発した1秒赤LED点滅アプリケーションコードが、そのままFRDM-KL25Zへ流用できることを前回投稿で示しました。ただ、どちらも同じARM Cortex-M0+コアのMCU評価ボードなので、読者インパクトは少なかったかもしれません。

そこで、LPC845 Breakout board(Cortex-M0+/30MHzコア)のLED点滅アプリケーションコードが、そのままCortex-M4/100MHzコアのLPCXpreosso54114へ流用できることを示します。異なるARMコア間でのアプリケーションコード互換の話です。

ARMコアバイナリ互換

Cortex-Mxのバイナリ互換性(出典:STM32L0(Cortex-M0+)トレーニング資料)
Cortex-Mxのバイナリ互換性(出典:STM32L0(Cortex-M0+)トレーニング資料)

ARMコアのバイナリ上位互換を示す図です(関連投稿:Cortex-M0/M0+/M3比較とコア選択の2章)。このバイナリコード包含関係は、Cortex-M0バイナリコードならCortex-M4でも動作することを示しています。

但し、この包含関係を理解していても、Cortex-M0バイナリコードをそのままCortex-M4へ流用する開発者はいないと思います。

ARMコアアプリケーションコード互換

Cortex-Mxのアプリケーションコード互換性
Cortex-Mxのアプリケーションコード互換性

MCUXpresso IDEのARMコアアプリケーションコード互換を示す図です。左がLPC845 Breakout board(Cortex-M0+/30MHzコア)の1秒赤LED点滅アプリケーションコード、右がCortex-M4/100MHzコアのLPCXpreosso54114の1秒赤LED点滅アプリケーションコードです。

コード差は、L59:LPCXpreosso54114評価ボード動作クロック設定:48MHz動作のみです。例えば、96MHzなどの他の動作周波数へ設定することも可能です。コード上で動作周波数を明示的に表示するために異なりましたが、機能的には両者同じコードと言えます(L59をマクロで書き換えれば、同一コード記述もできます)。

図下のInstalled SDK Versionが、どちらも2019-06-14で一致していることも重要です。Versionが異なると、例えばGPIOのAPIが異なることがあるからです。各SDKリリースノートでAPI差の有無確認ができます。※LPCXpreosso54114 SDKのMCUXpresso IDE設定方法は、コチラの投稿の5/6章を参考にしてください。

1秒赤LED点滅という簡単なアプリケーションですが、Cortex-M0+とCortex-M4の異なるARMコア間でコード互換性があることが解ります。

動作周波数の隠蔽とIO割付

評価ボード動作周波数が異なれば、無限ループ回転速度も異なります。従って、互換性を持たせるコード内に、無限ループ内の回転数でLED点滅させるような処理記述はできません。コードに時間要素は組込めないのです。

1秒点滅の場合は、L77:SysTick_DelayTicks()でループ回転数をカウントし、1秒遅延を処理しています。これにより、GPIO_PortToggle()が時間要素なしとなり、異なる動作周波数のARMコアでもアプリケーションコード移植性を実現しています。

SysTick_DelayTick()と1ms割込みによりカウントダウンする処理コードが下記です。ここも、割込みを利用することでコード移植性を実現しています。

動作周波数隠蔽によるARMコアアプリケーションコード移植性の実現
動作周波数隠蔽によるARMコアアプリケーションコード移植性の実現

左のLPC845 Breakout boardと、右のLPCXpreosso54114のコード差は、L16:赤LEDのIO割付のみです。評価ボード毎に異なるIO割付となるのは、やむを得ないでしょう。L12からL16のDefinition箇所を、別ファイル(例えばIODefine.hやUserDefine.h)として抽出すれば、同一コード記述も可能です。

ARMコアアプリケーションコード互換メリット

以上のように、ARMコアアプリケーションコード互換を目的にした記述や工夫も必要です。しかし、一旦互換コードを開発しておけば、開発資産として他のARMコア利用時にも使えます。その結果、開発速度/効率が高まります。

IoT MCUは、センサ入力やLED出力などのメイン処理以外にも、日々変化するセキュリティ処理への対応は、必須です。メイン処理が出来上がった後での、セキュリティ処理追加という手順です。

セキュリティ対策は、セキュリティライブラリ等の使用だけでなく、いつどのようにライブラリを活用するか、その時のMCU負荷がメイン処理へ及ぼす影響等、検討が必要な事柄が多くあります。

少しでも早くメイン処理を仕上げ、これら検討項目へ時間配分することがIoT MCU開発者には要求されます。この検討時間稼ぎのためにも、ARMコアアプリケーションコードの開発資産化は必須でしょう。

※プロトタイプ開発は、初めから厳しい条件で開発するよりも、最速のCortex-M4で行い、全体完成後Cortex-M0+/M3などへアプリケーションコードを移植するコストダウンアプローチも名案だと思います。

P.S.:2019年9月4日、MCUXpresso IDEがv11.0.1へ更新されました。旧MCUXpresso IDE v11.0.0 [2516]利用中の方は、Help>Check for Updatesではv11.0.1へ更新されません。新にMCUXpresso IDE v11.0.1 [2563]のインストールが必要です。新MCUXpresso IDEインストール方法は、コチラの4章を参照ください。

NXPのQUALCOMMによる買収、取りやめ?

日経新聞4月20日に、“クアルコム、止まらぬ受難 NXP買収に暗雲”記事が掲載されました。
記事では、トランプ米大統領のBroadcomのQUALCOMM買収禁止命令の報復として、中国当局が承認に難色を示し、7月25日まで買収期限を再延長し、最悪の場合、買収が取りやめになることもあるそうです。

2017年半導体売上高ランキング

2017年の半導体売上高ランキングもEE Times Japanで発表されました。日経記事に登場したイスラエル)NVIDIAが10位、オランダ)NXPは9位、米)QUALCOMMは6位、Broadcomは5位です。

半導体売上高トップ10ランキング(出典:記事)
半導体売上高トップ10ランキング(出典:記事)

仮にNXPの買収が取りやめになった場合、NXPにとってそれが良いのか悪いのかは、判りません。ただ急成長する自動車分野の制御にMCUの老舗、NXPの名前が残るのは悪くないと思います。※ルネサスMCUが、日立、NEC、三菱の統合であり、3社の名前の記憶が薄くなっていくのもさみしいものですから。

決着は、今年の夏頃(2Q 2018)になりそうです。

技術レベルとは異なる政治、経済次元での買収結果が、MCU技術にどのように影響するかは、注意深く見守る必要があります。

NXPのMCUXpresso Support Devices Table(Mar. 2018)へ更新

NXPのMCUXpresso Support Devices Tableが、3月9日更新されました。Change Logページ記載のとおりLPC80X、LPC8N04、LPC540XXが更新され、本ブログ対象のLPC8xxにもSDKやCFGが2Q 2018に提供予定です。LPCOpenライブラリのバグ問題が、新しいSDKで解決されることを期待しています。

NXP MCUXpresso Supported Devices Table (Mar 2018).
NXP MCUXpresso Supported Devices Table (Mar 2018). Product Family filtered with LPC 8xx.

関連投稿

NFC機能搭載マイコンLPC8N04、LPC800シリーズに追加

独自開発ボードのMCUXpressoプロジェクト作成方法

今回はNXP評価ボード以外の“独自開発マイコンボード”を使って、MCUXpressoの新規プロジェクトを作成する方法を、LPC810を例に示します。

New Project by Available boards
New Project by Available boards

上図NXP評価ボードを使ったMCUXpressoの新規プロジェクト作成は簡単です。現在LPC8xxマイコンには、6種のNXP評価ボードがあり、これらの中から使用ボード選択し、Nextクリックでダイアログに従っていけば新規プロジェクトが作成できます。

Preistalled MCUsプロジェクト作成

一方、LPC810(ROM/RAM=4KB/1KB)で独自開発したマイコンボードへ新規プロジェクトを作成する場合は、Preinstalled MCUsからLPC810を選びます。

New Project by Preinstalled MCUs
New Project by Preinstalled MCUs

Nextクリック>LPCOpen – C Project>Project name追記>Import>BrowseでLPCOpenライブラリをImportします(最新版LPCOpenライブラリはv3.02ですが、ここではMCUXpresso IDE v10.1.1 にプリインスト済みのv2.19を使っています)。

Import LPCOpen Library
Import LPCOpen Library

Importするのは、lpc_chip_8xx (lpc_chip_8xx/)です。lpc_board_nxp_lpcxpresso812は、NXP評価ボード利用時、lpc_chip_8xx関数を利用したマクロ関数です(マクロ関数は後述)。

インポートが完了するとNew Projectダイアログに戻ります。ここでLPCOpen Chip Library Projectのlpc_chip_8xx_libの_lib部分を削除すると、Nextボタンが“有効”になるのでクリックします。ポイントは、_libを削除することです。削除しないと、Nextは無効のままで先に進めません。

Import lpc_chip_8xx
Import lpc_chip_8xx

この後は、デフォルト設定のままでNextを何回かクリックすれば、独自開発ボードでの新規プロジェクトが作成できます。

なおLPC810は、ROM4KB、RAM1KBと極少ですのでデフォルトで使用となっているMTBやCRPは未使用に変更すると良いでしょう。

ちなみに、MTB、CRP未使用でLPC810へ弊社LPC8xxマイコンテンプレートのみを実装した時のメモリ使用量は、ROM88%、RAM2%です(debug configuration時)。これでは、残り部分へユーザ処理を追加するとすぐに容量オーバーになります。

対策は、コンパイラ最適化をデフォルトの“最適化なし(O0)”から“、1段階最適化(O1)”へ変更することです。
Project >Properties>C/C++ Build>Settings>Tool Settings>Optimization>Optimization Levelで最適化レベルが変更できます。O1レベルでも、かなりの使用量空きが確保できます。

Optimize for Debug
Optimize for Debug

但し、最適化には副作用も伴います。変数にvolatile宣言を付記するなどして、ツールが行う勝手な最適化への対策をしましょう。対策の詳細は、コチラなどを参照してください。

マクロ関数

LPCOpen Library Stack
LPCOpen Library Stack

LPCOpenライブラリは、層構成になっています。BOARD layerは、CHIP layerを使って上位の各ExampleへAPIを提供します。例えば、LPC812評価ボード実装済みのLED出力の初期化関数:Board_LED_Init()が、chip layerのChip_GPIO_…()を使っているなどです。

Macro Function
Macro Function

本投稿では、Board_LED_Init()をマクロ関数と呼びます。NXP評価ボードは、NXPから多くのマクロ関数が提供されますが、独自開発ボードでは、これらも必要に応じて自作する必要があります。

また、自動生成ソースコードにインクルードされるファイルも、NXP評価ボードでは無いためboard.hからchip.hに代わっていることにも注意しておきましょう。

MCUXpresso Generated Source
MCUXpresso Generated Source

ベンダ提供評価ボード活用の独自開発ボード

独自開発マイコンボードと、NXP評価ボードのIO割付が同じならば、MCUXpressoの新規プロジェクト作成時に本投稿で示したような神経を使う必要はありません。多くのマクロ関数もそのまま利用できます。独自開発ボードの新規プロジェクト作成でも、NXP評価ボードと全く同じになるからです。

独自にマイコンボードを開発する前に、ベンダ提供の評価ボードIO割付を調査し、独自開発へ適用できるか否かの検討をすることをお勧めします。

ベンダ提供評価ボードは、標準的なIO割付ですが、最も応用範囲が広い割付とも言えます。さらに、上述のようにソフトウェア開発、新規プロジェクト作成に対しても多くのメリットがあるのがその理由です。

NXPマイコンのNXP推薦開発環境

NXPは、Freescaleを買収しARMコアのマイコンラインアップが増えました。昨年発表の新しい統合開発環境MCUXpressoで増加ラインアップに対応中です(MCUXpressoサポート状況Excel表がコチラ)。

IDE、SDK:Software Development Kit、CFG:Config Toolsの3ツールから構成されるMCUXpressoのサポート状況から、新生NXPのARMマイコン開発環境を考察します。

もっと早く気が付いていれば…

このExcel表を見つけたのは、今年1月中。LPC824の最新LPCOpenライブラリv3.02に、昨年から継続するバグ解消が無いことが理由でした。何か変だと思い、NXPサイト検索で発見したのが同表です。

2017年7E目標のLPC824対応マイコンテンプレート開発前にこの表を見つけていれば、対応が変わっていただけに残念です(orz)。LPC800でフィルタリングしたのが下図です。

LPC8xx Recommended SDK
LPC8xx Recommended SDK (Source: Version 14)

LPC8xxシリーズは、LPCOpenライブラリはAvailableなものの、NXPはCode BundleがRecommended SDK:推薦Software Development Kitです。推薦環境以外でテンプレート開発したことになります。

Change Logページを見てもいつCode Bundleへ変わったか不明です。しかし、LPC8xxテンプレートV1開発時の2014年5月10日時点では、「LPCOpenがLPC812のSDK」でした(Legacyフォルダはあっても、Code Bundleなどありませんでした)。

LPC8xxシリーズは、IDEのみMCUXpresso IDEでSDK、CFGの計画はありません。つまり、NXP推薦Code BundleかLPCOpenを使いソフト開発が必要です。

Code BundleとLPC8xx

Code Bundleは、C:\nxp\MCUXpressoIDE_10.1.1_606\ide\Examples\CodeBundlesにあります。特徴は、ハードレジスタを直接アクセスするLegacyスタイルなので、従来の8/16ビットマイコン開発者に馴染み易く、これらマイコン置換え狙いのLPC8xxには、このスタイルの方が歓迎される可能性があります。

但し、LPC81x、82x/83x、84xとハードレジスタが微妙に変化していますので制御ソフトも変化します。LPCOpenのようにAPIでハード差を吸収する思想は少ない(無い)ようです。

気になる点が2つあります。最初は、サンプルソフトのヘッダーが簡素なことです。

ベンダ提供のサンプルソフトヘッダーは、細かな注意点などが30行程度記載されているのが普通です(左:Code Bundle、右:LPCOpen)。

Sample Software Hader
Sample Software Hader

Code BundleのHeaderは弊社マイコンテンプレートと同様簡素(上図は9行)で、間に合わせで開発した感があります。また、ソース内コメントも数人のエキスパート:上級者で分担してサンプルソフトを作成したように感じました。

Code Bundleの全サンプルソフトを動作テストした訳ではありませんが、LPCOpenのようなバグは(今のところ)ありません。SDKとしてLegacyスタイルに慣れた8/16ビットマイコンユーザが使うのは問題なさそうです。

2点目は、NXP推薦開発環境でCode Bundleなのが、LPC8xxシリーズのみの点です。

他のARMマイコンは、LPCOpenかまたはMCUXpresso SDKが大半です。旧NXPマイコンは、LPCOpenまたはMCUXpresso SDK、旧FreescaleマイコンはMCUXpresso SDKが主流です。

LPC8xxシリーズのみ今後もCode Bundleにするのか、または、他の旧NXPマイコン同様LPCOpenになるのかは、ハッキリ言って判りません。

LPC8xxマイコンテンプレートの対処

現在LPCOpenライブラリを使いLPC812のみ対応中のLPC8xxマイコンテンプレートV2.1を今後どうするかの案としては、

  1. LPC812、LPC824ともにLPCOpenライブラリバグ解消を待って改版
  2. LPC812、LPC824ともにCode Bundleを使い改版
  3. LPC812は現状LPCOpen維持、LPC824は、Code Bundleを使い改版(中途半端)

いずれにするか、検討中です。決定には、もう少し時間が必要だと思っています。

ミスリード(Mislead)のお詫び

これまで弊社は、LPC8xxシリーズのSDKはLPCOpenと思い投稿してきました。この投稿で、読者の方に誤った開発方向へ導いた場合には、お詫び申し上げます。申し訳ございません。

LPC8xxテンプレートをご購入頂いた方のテンプレート本体は、C言語のみでライブラリは使っておりませんし、マイコンにも依存しません。ご購入者様は、他マイコンも含めて流用/活用はご自由です。

LPCOpenで開発された関数を、Code Bundleへ変えたとしても、テンプレート本体はそのまま使えます。

あとがき

Code Bundleは、ハードレジスタをユーザ開発ソフトで直接いじる20世紀マイコン開発スタイルです。21世紀の現在は、ハードウェアに薄皮を被せAPI経由で開発するスタイルに変わりました。メリットは、ハードが変わってもユーザ開発ソフト側変更が少なく、マイグレーションに有利です。

ARMコアのマイコンは、全てこの21世紀スタイル:ARMスタイルです。ARMがCMSISなどを発表しているのは、ARMコアに依存しないユーザ開発ソフトを、資産として活用することが目的です(CMSISはこちらの投稿を参照)。

マイコンRTOSがWindowsのようにハードアクセスを全面禁止にすることはあり得ませんので、20世紀スタイルでRTOS化しても問題ありません。が、スイッチマトリクスが気に入っているLPC8xxシリーズだけが20世紀スタイルを使い続けるとは思えません。つまり、Code Bundleは、NXPサポート体制が整うまでの暫定措置だと思います。

この混乱の原因が、QUALCOMMによるNXP買収に絡んでないことを祈っています。

QUALCOMMのNXP買収、EUで一歩前進

2018年1月19日、米QUALCOMMの蘭NXPセミコンダクター買収計画がEU(欧州連合)当局で承認の記事が日経電子版に掲載されました。残るのは、中国の独占禁止法当局の承認だけです。遅れていた買収成立が一歩前進しました。

QUALCOMMのNXP買収
QUALCOMMのNXP買収

BLEとThreadソフト開発者必見動画

IoT通信規格のBLE 4.2とThread(802.15.4)両方をサポートするNXP)Kinetis KW41Z搭載の評価ボードを使ったBEL4.2とThreadメッシュ接続の開発Video(タイトルが以下Lesson 1~10)を紹介します。

Kinetis KW41Z Video Lesson Contents
Kinetis KW41Z Video Lesson Contents

BLEやThreadソフト開発者必見のLessons

内容、質ともに優れたVideoでMCUXpressoとSDKの使い方も良く解ります。特に興味深い内容とその出所が以下です。

  1. Bluetooth ClassicとBluetooth Low Energyの本質的な違い(Lesson 3、3分ごろ)
  2. Bluetooth ClassicとBLE間を接続するBluetooth Smart Ready(Lesson 3、6分ごろ)
  3. BLE接続の具体例(Lesson 3、19分ごろ)
  4. BLE/Thread接続に必要な知識(Lesson 3, 6)
  5. Threadが生まれた背景(Lesson 6、2分ごろ)
  6. Cortex-M0+/48MHz、512MB ROM、128KB RAM、FreeRTOSで実現するBLE/Thread IoT端末(Lesson  5, 9, 10)

BLEやThreadに関する情報は多くありますが、ソフト開発者の立場からは、本Lessonsが最も要領よくポイントをまとめています。

Kinetis KW41Z

KINETIS KW MCU FAMILY BLOCK DIAGRAM
KINETIS KW MCU FAMILY BLOCK DIAGRAM

Kinetis KW41Zの評価ボードは、以下の2種(Digi-Key価格)です。

低価格で有名なFRDM評価ボードですが、さすがに両プロトコル対応のKW41Z搭載ボードとなると$100以上します。Videoで使っているR41Z-EVALは、約$60と安く入手できます。但し、Lesson 10のBLEとThreadメッシュ切り替え接続の動作確認を行うには、同時に3台の評価ボードが必要です。

ThreadのみサポートのKW21、BLEのみのKW31もありますが、無線規格が乱立していて、どれが本命かを見極めるのが困難な現状では、両プロトコルサポートのKW41が安全でしょう。

API for IoT

MCUXpressoとSDKを使って、BLEまたはThread通信機能を持つIoT端末を開発する際に、プロトコルのどの部分の変更/修正が必要で、それがソース上のどこにあるか、全体の開発手順などはVideoを観ると良く解ります。

BLE Protocol Stack
BLE Protocol Stack

また、LEDなどのGPIO制御を行うSDKデモソフトとIoT通信の並列処理は、FreeRTOSを使って実現していることも解ります。簡単なIoT端末なら、このデモソフトに、外部センサ値をAD変換し、その変換データをクラウドのサーバーへIoT経由で送信する機能を追加しさえすれば、直ぐに開発できそうです。
※簡単なIoT端末は後述

BLEやThreadは、IoT通信の有力な候補です。しかし、IoTの通信プロトコルが何になるにせよ、IoT通信向けのAPIが決まれば、あまり気にする必要がない、というのが全Lessonを通しての私の感想です。

その理由は、デモソフト実装済みのGPIO制御はそのまま使えますし、FreeRTOSを使っていますので、外部センサ入力を定期的にADCする処理(ADCスレッド)と、ADC変換データをIoT通信APIへ出力する処理(IoT出力スレッド)の2処理を追加開発すれば良いからです。

ADCスレッドは、IoT通信規格には無関係です。一方、IoT出力スレッドは、Uart出力と同様のIoT APIが使える(用意される)と思います。NXP)LPC8xxマイコンのUart APIの例で示すと、Chip_UART_SendBlocking()が、Chip_IoT_SendBlocking()に代わるイメージです。IoT API利用条件が初期設定で満たされれば、ユーザは、通信速度や、通信プロトコルを意識せずにIoT通信を使えるようになると思います。

*  *  *

IoT通信規格が不確定な状況で、少しでも早くIoTやRTOSに慣れるには、R41Z-EVALは良い評価ボードです。また、FreeRTOSを使えば、48MHz動作のCortex-M0+、512MB ROM、128KB RAMで簡単なIoT端末が開発できそうな見通しもこれらLessonは、与えてくれました。是非、ご自分でご覧になってください。

簡単なIoT端末のイメージ

データ入力とGPIO出力を行うMCU端末で、IoT無線通信機能を備える。通信セキュリティを確保できるAES-128などの機能も備え、対象機器から取得したデータを安全にクラウド内のサーバーへ送信する。
サーバーは、対象機器データを人工知能を使って予測分析し、結果を端末へ送信する。
端末は、受信結果を基にLEDなどのGPIO出力を行い、オペレータまたはロボットが対象機器メンテナンス作業の手助けをする。

LPC8xxのGPIO制御とデバッグTips

NXP ARM Cortex-M0+マイコンLPCXpresso8xxのLPCOpenライブラリが、v3.01へ更新され、v2.x版から持ち越された多くのバグが修正されたようでした(結論から言うと、LPC81xにはバグが残っています。LPCXpresso8xxのLPCOpenライブラリv3.01は、前回の記事を参照してください)。

今回は、マイコン制御で最も基本となるGPIO制御を、MCUXpressoのサンプルソフトperiph_gpioと最新LPCOpenライブラリv3.01を使って解説し、さらにデバッグTipsを示します。

サンプルソフトperiph_gpioのGPIO API

LPCOpen v3.01のGPIO API数は、GPIO機能初期化、GPIOピン単位制御、GPIOポート単位制御の3種類で35個あります。全部使う必要はありませんので、最も基本的なGPIO APIを抜粋し使っているのがperiph_gpioで下記7個です。

periph_gpioのGPIO API一覧(その1)
GPIO API 概要
1 Chip_GPIO_Init(LPC_GPIO_PORT); GPIO機能初期化(=クロック供給)
2 Chip_GPIO_SetPinDIROutput(LPC_GPIO_PORT, 0, ledBits[i]); ピン(入)出力方向設定
3 Chip_GPIO_GetPinState(LPC_GPIO_PORT, 0, ledBits[LEDNumber]); ピン入力値取得
4 Chip_GPIO_SetPinState(LPC_GPIO_PORT, 0, ledBits[i], true); ピン出力値設定
5 Chip_GPIO_SetPinToggle(LPC_GPIO_PORT, 0, ledBits[LEDNumber]); ピン出力値反転

LPCXpresso8xxは、Portは0しかありませんので、「LPC_GPIO_PORT, 0,」は決まり文句、最後のパラメタは、GPIO0_xyzのGPIO論理ポート番号を示します。物理ピン番号ではない点に注意してください。

periph_gpioのGPIO API一覧(その2)
GPIO API 概要
6 Chip_GPIO_SetPortMask(LPC_GPIO_PORT, 0, ~PORT_MASK); ポートマスクレジスタ設定
7 Chip_GPIO_SetMaskedPortValue(LPC_GPIO_PORT, 0, count); ポート出力値設定(マスクレジスタ経由)

ポート単位のGPIO APIは、複数の出力ピン出力を同時に設定するもので、バス出力時に便利です。これら7個のGPIO APIのみを習得していれば、基本的なGPIO制御ができます。

評価ボード実行結果

LPC81xは、LPCXpresso812、LPC82xは、LPCXpresso824-MAXの評価ボードで実行した結果が下図です。

periph_gpio実行のデバッグ画面
periph_gpio実行のデバッグ画面(赤色がLPC824、青色がLPC812)

LPC81xとLPC82xでは、同じソースでも、ポート出力値が異なります。期待値は、LPCXpresso824-MAXでしか得られません。つまり、LPC81xにはGPIO APIのポート制御にバグがあることが判ります。

デバッグTips

ここで、デバッグのTipsを解説します。

MCUXpressoのローカル変数は、Quick Start ViewのVariablesタブで、周辺回路状況は、Workspace ViewのPeripherals+タブで表示可能です。適当な場所にブレークポイントを設定しF8クリックで、ブレークポイントまで実行します。評価ボード実行結果は、この操作で得られたものです。

現行版MCUXpressoは、デバッグでよく使うファンクションキーのツールチップが一部表示されません。
F8(実行)と、F5(ステップ実行)、F6(ステップオーバー:関数に入って処理「後」停止)、F7(ステップリターン:関数に入った状態で処理「後」停止)を覚えておくとデバッグ効率が良くなります。

LPCOpenライブラリv3.01のLPC81xポート制御、バグ回避方策

LPC812とLPC824はGPIOレジスタ構成が異なります。後で開発されたLPC824の方が、より制御し易いレジスタを備えています(ハードウエアマニュアルより抜粋)。

LPC824とLPC812のGPIOレジスタ比較
LPC824とLPC812のGPIOレジスタ比較

バグがあったLPC81xのポート出力値設定の代替として、他のGPIO API利用または、直接ハードレジスタ操作などを試しましたが、LPCOpen v3.01では、代替方法が見つかりません。思うにLPC81xライブラリの結構深い場所にバグがある可能性があります。

そこで、LPC81x動作には、旧LPCOpenライブラリv2.15を、LPC82x動作には、最新LPCOpenライブラリv3.01を使ってLPC82xテンプレート開発をすることに方針変更しました。当初目標のLPC8xxテンプレート、つまりLPC82xとLPC81xの両方を同じテンプレートソースで実現することは、残念ながら諦めました。

MCUXpressoでの旧LPCOpenライブラリv2.15の使い方

MCUXpressoは、このようなバグの場合に備えて旧LPCOpenライブラリ群も備えています(C:\nxp\MCUXpressoIDE_10.0.2_411\ide\Examplesフォルダ参照)。最新版MCUXpresso IDE v10.0.2_411でもLPCOpenライブラリv3.01が同封されていないのも、本稿で示したバグが理由かもしれません。

旧LPCXpressoプロジェクトをMCUXpressoで開こうとすると、下記ワーニングが出力されます。

Older Workspace Version Warning
Older Workspace Version Warning

旧LPCXpressoとMCUXpresso両方を使い続ける方は、LPCXpressoプロジェクトをコピーして別名のプロジェクトを作成した後に、MCUXpressoで開くと良いでしょう。

LPC81xテンプレートV2.1は、テンプレートプロジェクト内にLPCOpenライブラリv2.15を装着していますので、そのままMCUXpressoで開いても問題なく動作します。

*  *  *

LPCOpenライブラリv3.01を使った新しいLPC82xテンプレートV3の開発は、7E目標で進行中ですが、上記のようなLPCOpenライブラリv3.01バグがあり、予定より難航しています。ちなみにUart関連は、LPCOpenライブラリv3.01でかなり改善されました。

また、MCUXpressoは、Ctrl+スペースキーによる入力補完機能も実装されており、使い勝手は向上しています。旧LPCXpressoを使う必要性は低いと思います。

LPC8xxテンプレートV3完成は、今しばらくお待ちください。

MCUXpreosso IDEリリース

3月22日、NXPより旧LPCXpresso IDEとKinetis Design Studio IDEを統合した新しいMCUXpresso IDEがリリースされました。見た目や操作感は、LPCXpressoに近く、Kinetis Design Studio:KDSユーザには、かなり違和感があるかもしれません。

MCUXpresso IDE
MCUXpresso IDE

LPCXpressoやKinetis Design Studioと共存可能

LPCXpresso v8.2.2_650やKinetis Design Studio 3 IDEと、新しいMCUXpresso IDE v10.0.0_344は、Windows 10 PC上に共存可能です。MCUXpresso_IDE_Installation_Guideに詳細が記載されています。

LPCXpressoユーザは、旧プロジェクトの移行方法などもこのガイトに記載されていますので参照してください。

KDSユーザは、Processor Expert: PEが実装されていませんので、Software Development Kit: SDKサイトへアクセスし、Build your SDKで評価ボードまたはMCU毎に構成設定し作成後、APIのダウンロードが必要です。しかし、PEほど使い勝手は良くないでしょう。この方法に慣れるか、または、PEのアドインも可能かもしれません。詳細判明しましたら、本ブログに記載します。

LPCXpresso に近いAPI提供方法

IDEのAPI生成/提供方法で示した3方法では、私の予想に反して最も旧LPCXpressoに近く、オンラインで構成設定→IDEへダウンロードしてのAPI利用となりました。このオンラインSDKをIDEへ直接インストールすることもできますが、FreescaleとNXPの合併で多数のMCUをサポートするので、軽いIDEのために、API提供SDKをIDEから切り離したと思います。

MCUXpressoでは、LPCXpressoで使っていたLPCOpenライブラリも内包されており、そのまま使えます。

両社合併で新IDEも折衷的なものです。旧環境に慣れた開発者には、オンラインSDKに慣れるか悩みどころです。特に今春発売されたMCU以外の開発にはメリットが少ないので、Windows 10 1703を待ってからインストールするのが良いかもしれません。