FreeRTOSは、スタックとヒープの管理に単一の大きなメモリ領域を定義して使用します。これは単純にバイト配列であり、そのサイズはconfigTOTAL_HEAP_SIZE
シンボルで指定され、FreeRTOSConfig.h
になります。 FreeRTOSは、pvPortMalloc
関数を使用してこのメモリ領域にタスクスタックを割り当てます。したがって、ここでの主な目標は、FreeRTOSヒープ領域を外部SRAMに配置することです。
FreeRTOSヒープメモリ領域は、変数がucHeap
と呼ばれ、(標準ライブラリのmallocを使用していますheap_3.c
を除いて、それが任意のカスタムヒープ領域を定義していません)heap_*.c
で定義されています。コンパイラ拡張を使用してセクションを設定することができます。 GCCの場合、それは次のようになります:
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ] __attribute__ ((section (".sram_data")));
このカスタムセクションを外部SRAMに配置するようにリンカスクリプトを設定する必要があります。これを行うにはいくつかの方法があり、使用しているツールチェーンに依存します。これを行うにはGCC一つの方法は、SRAMとSRAM領域に追加する".sram_data"
ためのセクションのためのメモリ領域を定義するだろうと、のようなもの:
MEMORY
{
...
/* Define SRAM region */
sram : ORIGIN = <SRAM_START_ADDR>, LENGTH = <SRAM_SIZE>
}
SECTIONS
{
...
/* Define .sram_data section and place it in sram region */
.sram_data :
{
*(.sram_data)
} >sram
...
}
は、これは一方で、外部SRAMにucHeap
エリアを配置します他のすべてのテキストセクションとデータセクションは、デフォルトのメモリ領域(内蔵フラッシュとラム)に配置されます。
いくつかの注意事項:
- あなたが前に任意のFreeRTOS機能(のような
xTaskCreate
)を呼び出すにSRAMコントローラ/ FSMCを初期化してください
- あなたが作業を開始すると、すべてのスタックに割り当てられた変数はに配置されます
ucHeap
(つまりext RAM)ですが、グローバル変数は引き続き内部RAMに割り当てられます。それでも内部RAMサイズの問題がある場合は、コンパイラの拡張機能(ucHeapの場合)を使用して".sram_section"
に配置する他のグローバル変数を設定できます。
- コードで動的メモリ割り当てを使用する場合は、
pvPortMalloc/vPortFree
stdlib malloc/free
。これは、異なるメモリを使用してpvPortMalloc/vPortFree
でダイナミックタスクの作成/削除とメモリ割り当てをたくさん行っている場合、pvPortMalloc/vPortFree
のみがext RAMのucHeap領域を使用します(そして、スレッドセーフです。プラスです)
- ブロックサイズは、
heap_2.c
の代わりにheap_4.c
を使用することを検討してください。いくつかの異なるブロックサイズを使用する場合heap_4.c
が
別の(そしておそらくより簡単な)単一の大きなブロックに隣接する空きメモリブロックを結合することが可能である一方heap_2.c
溶液がポインタとしてucHeap変数を定義することで、メモリの断片化の問題があります
static uint8_t * const ucHeap = <SRAM_START_ADDR>;
これは特別なリンカースクリプト編集を必要とせず、すべてをデフォルトセクションに配置することができます。このソリューションでは、リンカはヒープ用のメモリを明示的に予約しないので、(ヒープ領域がext RAMに適合しないなどの)潜在的に有用な情報/エラーが緩和されることに注意してください。しかし、外付けRAMにucHeap
しかなく、外付けRAMサイズよりも小さいconfigTOTAL_HEAP_SIZE
があればうまくいくかもしれません。
外付けSRAMに正確に配置する必要はありますか?大きなデータ構造ですか?すべての読み書き可能なデータ? SRAMから実行するにはコードが必要ですか?それともフラッシュに常駐できますか? –
当初の考えは、すべてを外部のラムに置くのが最も簡単なことでした。実際にMCUにとって大きすぎる暗号鍵と計算があります。しかし、何らかの理由で、とにかくそれを行う必要があります。コードはフラッシュからちょうど良いので、私はスタックとヒープを意味するすべてのものから実行できます。 – evading
どのバージョンのFreeRTOSヒープ管理ソースファイル(heap_1.c、heap_2.cなど)を使用していますか?私はFreeRTOSが(pvPortMallocを使って)ヒープにタスクスタックを割り当てていると思うので、SRAMに移動する必要があるのは唯一のことかもしれませんが、使用しているヒープ_ *。cのバージョンによって大きく変わります –