2018年7月28日土曜日

メモ:arm-none-eabi-gccのセクション

 arm-none-eabi-gccで変数を指定したセクションに配置する - Catalystize!

 CubeMXが吐くリンカスクリプトでCCMRAMに割り当てるには __attribute__((section(".ccmram"))) と書けばいいらしい。

 例えばFreeRTOSのヒープ領域をCCMRAMにする場合は

#if (configAPPLICATION_ALLOCATED_HEAP == 1)
uint8_t ucHeap[configTOTAL_HEAP_SIZE] __attribute__((section(".ccmram")));
#endif

 というふうになる。

***

 STM32F3のCCMは4kしかない。FreeRTOSのヒープを置くにはちょっと狭い。小さなタスク3個程度+小さなqueue2個くらいなら入るけど、それより大きくなると心もとない。
 Cubeはいちおうヒープ領域が足りない場合は警告を出すけど、Queueのサイズはコードを解析して構造体の大きさを調べないとわからないので、Queueの分は反映されていないはず。

 CCMはDMA領域に使えないので、大きなバッファを使うDMA転送には活用できない。

 なんともままならない。


 RAMの使用量の見方がよくわかってない。
 dataが5104、bssが3860、らしい。和がトータルの使用量かな? とすると8964byteが使用されていて、残りがスタックとヒープに使われる、という感じ?
 今回のマイコンだとRAMが12Kあるので、まだカリカリする必要はなさそう。
 今回はmalloc/newでヒープ領域を使うようなコードは無いし、もうちょっと多めに確保しても大丈夫そうだ。といってもFreeRTOSのヒープはキロバイト単位で持っていくので、あっという間に底をつきそうだが。あんまりキチキチまで使うとスタックが足りなくなるし。

***

追記
 CubeのTaskやQueueをStaticにすれば、管理構造体やデータ領域をグローバル変数で宣言できる。こうするとFreeRTOSのヒープ領域を使わずに済む。
 基本的にタスクやキューを生成したり削除したりといったことは行わないので、staticで問題ない。はず。
 むしろ、FreeRTOSのConfigでMemory AllocationをStaticにしてしまって、ヒープ領域の確保自体も行わない、というのもアリかも。

 staticの場合はfreertos.cに各構造体やバッファが宣言されるが、これはCubeの自動生成エリアなので、書き換えてもCubeで書き出すたびに戻されてしまう。
 この宣言の部分でセクションの指定を書けば、あるタスクのスタックはCCMへ、CCMに入り切らないものはRAMへ、というふうにできるのだが。


 あと、staticだとQueueの構造体の大きさが0だとコケるっぽい。
 先にキューだけ作って、とりあえずコンパイル通るように空の構造体を作っておいたら、動作しなかった。コレがわかるまであちこちいじくり回してしまった。適当な変数を1個入れておけば動くので、仮に構造体を作るときも適当な変数を作っておくように。。

0 件のコメント:

コメントを投稿