2017年5月13日土曜日

F4Cube

 STBee F4miniのコードをCubeで生成していろいろ遊んでる。とりあえずFreeRTOSでUARTが動くところまでは作れた。

 いろいろとつまずいてるのだけど、とりあえずあとから来る人に「ここに石があるかも!」みたいな感じで書いておきます。

 FreeRTOSをビルドしようとして機械語関係っぽいエラーが出た場合はFPU周りのGCCオプションを要確認。-mfloat-abi=hard -mfpu=fpv4-sp-d16あたりが必用になる。うっかり忘れててかなり悩んだ。FPUを使わなくてもソフトで浮動小数点演算ができるので、簡単にprintfで浮動小数点を表示するくらいじゃ気が付かない。
 ちなみに、FPUを使った際のベンチマークがF4デジタルオーディオプレーヤーのページにあるので、比較してみても良いかも。正常にFPUが動作していれば168MHzで4秒、ソフトだと単精度で30秒ちょっと、倍精度だとさらにかかる(倍精度はすべてソフトで計算するので時間がかかる)。

 HALはかなり抽象化されているが、行き過ぎな気もする。例えばRTOSの機能を使う場合、FreeRTOSの関数を呼び出す必用はなく、Cubeが提供するラッパーを呼べばいい。これなら、FreeRTOS以外のRTOSを使う場合でも、ラッパーを交換するだけで動く。
 しかし、ラッパーを経由しているので、単純な関数(あるいはマクロ展開)を呼ぶ場合でも、複数の関数呼び出しが発生する。パフォーマンスを優先する部分はFreeRTOSの関数を直接呼び出すと楽。
 またSTM32のハードウェアアクセスもHAL経由では冗長な場合がある。そういう場合はstm32f4xx_ll_hoge.hをインクルードして、LL_hoge_hugaのような関数を使うと、レジスタを直接操作できる。やってることはStdPeriphLibと同じだが、命名規則とか関数の取り方は違うので注意。LLは単純な機能の場合、インライン展開されるので、StdPeriphLibより高パフォーマンスを期待できる。

 割り込みハンドラ内でフラグチェックを行う場合、チェックする順番が重要な場合がある。例えばレジスタの読み出しでクリアされるフラグが有ったりする。リファレンスマニュアルを参照のこと。
 他にも、LLでUSARTのフラグチェックを行う場合には、TXEより先にRXNEのチェックが必用だった。TXEをチェックした後にRXNEをチェックするとハングアップした。RMを読んだ限りでは特に注意が必要な感じはしなかったが、いよいよもってバグの原因がわからない時は、プログラムの順番を変えてみるのも試す価値はある。

 HALやCubeに限らないが、FreeRTOSでスタックが足りないと厄介な動作不良を引き起こす。例えばprintfはスタックを多く使うので、特に注意が必要。
 メモリ管理が厳密ではない環境では、スタックオーバーフローが即ハングアップになるとは限らない。いろいろ試して、「このハングアップは何か法則性がありそうだぞ?」と思っても、実は何の法則性もなく、単純にスタック不足だったということはよくある。
 試作段階では可能な限り多くのスタックを割り当てるべき。ある程度機能が出来上がってきたところで、必要以上の割当があれば割当を減らす。


 今のところは、これくらいか。まだまだいろいろ有るんだろうけど。

0 件のコメント:

コメントを投稿