2023年05月27日

pico-sdk 最適化オプション

RP2040をC言語で使用する場合にpico-sdk+pico-project-generatorを使用することが多いと思います。先日、pico-sdkを使用していて、意図通りにRP2040が動かないことがありました。この原因として最適化オプションが働いて意図せず、変数等が削除されてしまったことでした。多くはvolatile等のオプションを変数に付与することで解決しますが、プロジェクトが大きくなるとプロジェクト全体の最適化オプションを変更した方が楽な場合が多々あります。

今回はpico-sdk+pico-project-generatorでビルドのオプションを変更する方法について紹介します。多くの方法としては下記のようにcmakeの引数でビルドオプションを指定することが一般的ですが、毎回、ビルドの度に指定するのは面倒です。

cmake -DCMAKE_BUILD_TYPE=Debug -DPICO_DEOPTIMIZED_DEBUG=1
make -j4


pico-sdk+pico-project-generatoの場合、自動的にプロジェクトフォルダ内にCMakeLists.txtが生成されます。今回はプロジェクトフォルダ内のCMakeLists.txtにビルドオプションを書き込んで、ビルドオプション指定を自動化する方法を紹介します。
プロジェクトフォルダ内のCMakeLists.txtをテキストエディタで開き、先頭のset部分に下記のスクリプトを追加します。

set(CMAKE_BUILD_TYPE "Debug")
set(OPTIMIZATION_FLAG 1)

実際に書き込んだイメージは下記です。

option.jpg


なお、デフォルトは
set(OPTIMIZATION_FLAG "-Os")
になっているようでサイズ最適化のため、最適化オプションが働いて意図せず変数が削除される可能性があります。

急に意図通りにRP2040が動かなくなり、最初はpico-sdkのバージョンやcmakeのバージョン等が原因と思いましたが、結局、ビルドの最適化オプションが原因であると分かりました。eclipseベースの開発環境では簡単にビルドの最適化オプションを確認、変更できますが、cmakeベースでは気づきにくいため、注意が必要だと思いました。
posted by Crescent at 00:00| Comment(0) | TrackBack(0) | 組込ソフト | このブログの読者になる | 更新情報をチェックする

2023年02月04日

メモリ空き領域確認方法 PICO-SDK版

以前にSW4STM32環境でのメモリ領域を確認方法を紹介しましたが、今回はRP2040のPICO-SDK環境でビルド時にメモリ領域を確認する方法を紹介します。

簡単なプログラムであれば、FlashやRamの領域を気にする必要はありませんが、大量にメモリを使用する場合はどれくらい既に占有しているのか気になると思います。リンカの設定を少し追加することで詳細情報をビルド時のコンソールに表示することが可能です。

デフォルトではFlashやRamの領域の情報は表示されません。表示させる場合はプロジェクトフォルダ内の「CMakeLists.txt」のtarget_link_libraries以降に下記のスクリプトを追記します。下記のスクリプトのPROJECT_NAMEの部分はプロジェクトに応じて変更してください。

target_link_options(PROJECT_NAME PRIVATE "LINKER:--print-memory-usage")

実際にプロジェクト名がProjectionBallの場合で追加した際のイメージは下記の通りです。

option_image.png


追記すると下記のようにビルドの度にFLASHとRAMの占有率が表示されるようになります。

Memory region Used Size Region Size %age Used
FLASH: 43380 B 2 MB 2.07%
RAM: 79212 B 256 KB 30.22%
SCRATCH_X: 2 KB 4 KB 50.00%
SCRATCH_Y: 0 GB 4 KB 0.00%

なお、STM32等にはない、SCRATCH_X、SCRATCH_Yの領域はマルチコア利用時の振り分けに使用される領域なようです。


memory_usage.png


RP2040でも大量にメモリを使用するプロジェクトの場合にはぜひ、このような設定を有効化してみてください。
posted by Crescent at 00:00| Comment(0) | TrackBack(0) | 組込ソフト | このブログの読者になる | 更新情報をチェックする

2022年11月26日

組込系機械学習ライブラリ

今回はマイコン等に組込可能な機械学習ライブラリを調査してみました。マイコン等の組込系で使用するため、C/C++で利用可能な代表的なライブラリの特徴を調べてみました。

 最も良く使用される組込系機械学習ライブラリです。ただ、組込系の場合、ARMのライブラリと依存関係があるため、ARM以外のPICやAVRといったCPUではそのままでは利用できません。RISCV等をターゲットにしたARM以外に実装した例もありますが、ライブラリが非常に大きく、ポーティングに難ありなようです。

 STM32マイコンに実装する場合にCubeMXと統合されたUIで利用できる機械学習ライブラリです。KerasやTensorFlow等の学習結果を簡単に組み込むことが可能です。また、学習結果の圧縮やテスト等が容易にできるため、STM32マイコンであれば非常に便利です。一方でSTM32マイコン以外では使用できなく、昨今の半導体不足の影響をモロに受けているため、当面は安定した入手が難しい可能性があります。

 scikit-learnもしくはKerasの学習結果をC/C++に変換することができます。Pythonで学習結果を読み込ませると自動的にC言語でヘッダーファイルが生成され、そのままマイコンのプロジェクトソースに組み込むことが可能です。1つのヘッダーファイルをプロジェクトソースに組み込むだけて利用できるため、他のライブラリのように複数のソースコードをプロジェクトに追加する必要もなく、非常に簡単に組み込むことが可能です。また、ライブラリ自体非常に軽量なため、小規模なモデルであれば8ビットマイコン等にも組込可能です。ただし、利用可能なモデルに制約があります。

ELL
 マイクロソフトが提供する組込向けの機械学習ライブラリです。主にC++で実装されています。組込向けといってもマイコン等ではなく、raspberry piといったSBC等をターゲットにしているようです。ここ数年の開発ペースは落ちているようです。

その他

DLib
FANN

 実際にSTM32 Cube AI、Tensorflow Lite、emlearnを使ってみました。印象として、ターゲットとなるマイコンでサンプルがあれば、Tensorflow Liteはネット上に情報が多く、利用しやすいと思いました。初心者でも簡単に効率よく、推論結果を評価したりできる点ではSTM32 Cube AIがお勧めです。また、利用可能な機械学習モデルに制約があるものの、どのようなマイコンにも簡単に組み込むことができ、C言語で移植性が高いという面ではemlearnがお勧めでです。個人的にはSTM32、RP2040、PIC32マイコン等の様々な環境で利用することを想定し、今後はemlearnをより使ってみたいと思いました。
posted by Crescent at 00:00| Comment(0) | TrackBack(0) | 組込ソフト | このブログの読者になる | 更新情報をチェックする

2022年05月07日

PIC32 C++プロジェクト

今回はPIC32マイコンでC++ (CPP) プロジェクトを作成する方法について紹介します。といっても記事にする程でないほど簡単でした。

STM32マイコンのSW4STM32やCubeIDEではC++プロジェクトへの変換作業等が必要でしたが、MPLAB X(v5.45) + XC32(v2.50) +Harmony3では特に変換作業等必要なく、cppファイルと.hppファイルを追加するだけでした。また、ライブラリやプロジェクト、コンパイラ等はC++に対応済のため、追加設定は不要です。そのため、非常に簡単に実装できます。

追加するcppファイルと.hppファイルとして、ラッパーとなるwrapper.cpp、wrapper.hpp、LED点滅用の関数LedBlink.cpp、LedBlink.hppをプロジェクトに追加します。また、app.cからラッパー関数を呼び出すためのcpploop();を追加しました。各ファイルの詳細についてはこちらにアップロードしたため、割愛します。

通常のプロジェクト同様にLedBlink.cpp内でブレイクポイントを置いてデバッグもできました。

PIC32CPP.JPG

思った以上にすんなりC++ (CPP) プロジェクトを動かすことができたため、今後はパワフルなPIC32マイコンを活かして、機械学習系のライブラリ等にも応用してみたいと思います。
posted by Crescent at 00:00| Comment(0) | TrackBack(0) | 組込ソフト | このブログの読者になる | 更新情報をチェックする

2022年03月12日

PIC32 ウォッチドッグタイマ

 今回はPIC32マイコンのWDTの設定方法を紹介します。WDT(ウォッチドッグタイマ)は名の通り、MPUの動作を見張る番犬です。WDTを有効化するとMPUに異常な処理が発生した場合や意図しない処理の無限ループに入ってしまった場合に異常としてMPUをリセットさせることができます。PIC32マイコンにはWDTの他にDMT(デッドマンタイマ)も搭載されています。目的と用途が異なるため、ここでは詳細は省略しますが、WDTはスリープ等からの復帰にも使用でき、汎用的でざっくりとした時間間隔での監視が可能です。一方、DMTはスリープ復帰には使用できませんが、設定した命令数(処理)に対して細かく監視間隔を設定できます。DMTは少し特殊な用途となるため、今回はWDTのみ紹介します。

 WDTの動作原理として、監視の時間間隔を予め設定し、監視を開始します(WDT_Enable)。そのあと、コード上で定期的にWDTカウントリフレッシュ関数WDT_Clearを呼び出します。正常な場合は予め設定した監視時間よりも前にWDT_Clear関数で正常に動いていることをWDTに知らせます。何かしらの異常が発生した場合は予め設定した監視時間になってもWDT_Clear関数による知らせがWDTにないため、監視時間を超えた時点でWDTが強制的にMPUのリセットを実行する仕組みです。正常動作にも関わらず、監視時間に達してリセットされてしまうということがないように、ある程度余裕のある監視時間を設定すべきです。ただ、余裕にしすぎると万一、異常な状態になった場合にリセットがかかるまでに時間を要することになるため、バランスを見て設定する必要があります。例えば、長い処理ではリフレッシュ関数を所々に予め入れておくといった対応が想定されます。

Harmoney3のProject GraphのSystem項目から設定することができます。


wdt0.jpg

WDTの設定については特に分かりずらく、WDTのパラメータ設定はDEVCFG1から設定します。WDTPSのパラメータを変更することでリセットまでの監視時間を変更することが可能です。

wdt1.jpg

 一方、WDTの有効、無効はDEVCFG1とは別のWDTの項目にチェックを入れることで自動的にWDT関連の関数ライブラリコードが生成されるようになります。WDTPSのパラメータの設定を秒数としてWDT項目から確認することができます。

wdt2.jpg

 パラメータ設定DEVCFG1と有効可否設定WDTが分かれているため、初めてだと戸惑いました。WDTの有効、無効は他のペリフェラル機能と同様にAvailable Componentsに項目を入れた方が直感的で分かりやすいと思いました。
posted by Crescent at 00:00| Comment(0) | 組込ソフト | このブログの読者になる | 更新情報をチェックする