STBee F4miniに使われてるSTM32F405RGTには、メモリが192kB搭載されている。
0x10000000からの64kB、0x20000000から112kB、0x2001C000からの16kBの3種類。
112kと16kは連続していて、128kBとして使える。この2箇所は同時にアクセスすることができるので、例えば112kをメインのメモリとして使い、16kはUSBやEthernetのバッファとして使う、というような用途らしい。
64kはARMコアとは接続されているが、DMAバスとは接続されていないので、64k領域にある配列をDMA転送しようとするとハングアップするらしい。
今までは128kをメインのメモリとして使い、64kをスタックとして使っていた。これはねむいさんのリンカそのもの。しかし、FreeRTOSを使っているので、スタックはほぼ全く使っていない。
今回、試しにFreeRTOSのスタックを64k領域に配置し、128kをそれ以外に使うようにしてみた。FreeRTOSは今のところ16kほど使ってるので、まだ48kほど開いてる。DMA転送で使う場合はstaticで宣言して128k領域から確保すればいい。またmallocも128k領域から取ってくるようになる。
配列のアドレスを指定するのは、リンカスクリプトとかでうまくできるのだろうが、方法がわからなかったので、 static uint8_t *ucHeap = (uint8_t *)0x10000000; のように、直接指定することにした。これはFreeRTOS/portable/MemMang/heap_4.cの100行目あたりに書いてある。配列の宣言をポインタに置き換えたもの。リンカスクリプトには64k領域を書いていないので、コンパイラがこの領域を使うことはできない。configTOTAL_HEAP_SIZEは64KiBにしておけばok。
ということで、微妙に使い勝手の悪い64k領域をそれなりに活用しつつ、128k領域を目一杯使えるようになった。
mallocで確保できる領域も増えたので、動的にメモリを使う機能も使いやすくなった。
Luaを走らせたいんだけど、ちょっと苦戦中。
追記
もうちょっとスッキリした方法(たぶん)。
FreeRTOSConfig.hに #define configAPPLICATION_ALLOCATED_HEAP 1 を追加する。
freertos_heap.cという、FreeRTOS.hをインクルードし、uint8_t ucHeap[configTOTAL_HEAP_SIZE]; と配列だけを宣言したソースを作る。
リンカスクリプトのセクションに
.freertos_heap_sec :
{
*freertos_heap.o(.bss .bss.*)
} >RAM3
を追加する。
これで、FreeRTOSのヒープ領域をRAM3に確保できる。
main.cの最初のほうでスタックのアドレスを変数に保存して、後で表示してみると、0x1000000の領域に確保されている。FreeRTOSのスレッド内でスタックのアドレスを見ても、0x10000000の領域に確保されている。
ということで、64kの領域にFreeRTOSのヒープを確保しつつ、残りの領域はOS外のスタックを確保し、残りの128kをmallocに使う、という感じになった。今のところ、FreeRTOSでは16kくらいしか使ってないらしいが、とりあえず32kを確保している。
今までのheap_n.cを書き換える方法だと、Cubeで出力するたびに戻されるので、面倒だと思う(未確認)。今回の方法だと、一応Cubeの制御外のはず(未確認)。
0 件のコメント:
コメントを投稿