STM32のCCMRAMセクションでのFreeRTOSヒープの配置

STM32F407に基づいて1つのデバイスを開発したとき、RAMが不足しているという問題に直面しました。デバイス自体の目的は重要ではありませんが、元のコードがデスクトップシステム用に作成されており、FreeRTOSを実行しているマイクロコントローラーに移植する必要があることが重要です。また、ソースコードはC ++で記述されており、RAMを節約するという問題も提起されなかったため、対応する問題が発生しました。



私は本当にコードの最適化に従事したくなかったと同時に、新しいバグを見つける際の問題を追加しました。したがって、このバージョンのマイクロコントローラーには、現在使用されていない追加の64K RAMセグメント(CCM SRAM)が搭載されていることをタイムリーに思い出しました。ユーレカ-これが解決策です!



しかし残念ながら、すべてがそれほど単純ではないことが判明しました。





既製のソリューションの検索結果



CCMRAMの公式ドキュメントに は、実行可能コード、スタック、または個々の変数を配置するための例が記載されています。



フォーラムを検索すると、CCMRAMを使用するさまざまな方法へのリンクがいくつか見つかりましたが、残念ながら、それらはすべて、公式ドキュメントに記載されている方法のさまざまなバリエーションでした。そして、それらはすべて、各関数または変数を宣言するときに属性を追加するためにソースコードをシャベルで調べる必要がありました。



GCCの場合、私の場合、次のようなものです。



__attribute__((section(".ccmram")));
      
      





さらに、一部の変数にはデフォルト値があり、ファームウェアの起動時にそのような変数が初期化またはゼロ化された変数用に別の領域にコピーされるようにブートローダーを変更する必要があります。



さて、最後の難しさは、CCMRAM自体の制限でした。DMAがアクセスできない別のバスにハングアップし、ダイレクトメモリアクセスを非常に積極的に使用することが計画されていました。



言い換えれば、1つの問題を解決すると、誤って他の問題を追加し、デバッグを掘り下げて、導入されたバグを見つける可能性があります。



幸い、FreeRTOSの側で簡単な解決策を見つけることができました。



ヒープサイズはCCMRAMセグメントのサイズよりも小さく、ヒープをこのパーティションに移動するという決定は自明でした。



そして、最小限のコード変更でこれを行うことができました。



  1. 新しいセクションがldファイル(私の場合はSTM32F407VGTX_FLASH.ld)に追加されます。



    .ccmram :
     {
       . = ALIGN(8);
       . = . + _Min_Heap_Size;
       . = ALIGN(8);
     } >CCMRAM
          
          



  2. 「._user_heap_stack」セクションで、行がコメント化または削除されます



    /*    . = . + _Min_Heap_Size; */
          
          





    RAMサイズが不十分な場合にリンカが警告を発行するには、_Min_Heap_Sizeのが必要です。
  3. プログラムの本体に単一の変数が追加されます。



    uint8_t ucHeap[ configTOTAL_HEAP_SIZE ] __attribute__((section(".ccmram")));
          
          



  4. また、プロジェクトをビルドするときに、プリプロセッサ定義が追加されます



    configAPPLICATION_ALLOCATED_HEAP=1
          
          





その結果、ソースコードの編集回数が最小限のCCMSRAMのFreeRTOSがたくさんあります。



All Articles