タイトルが示すように、FLASH (たとえば STM32 µC) でより多くのスペースを使用するのは何ですか? グローバル変数を宣言するか、関数内で静的変数を宣言しますか? それとも同じスペースを取りますか?私の理解では、両方の変数はプログラムのランタイム全体で利用できます。スコープが異なるだけです。
3 に答える
0 で初期化されたグローバル変数と静的変数を持つことができます。それらは、プログラムの開始時に割り当てられてゼロにされるメモリ位置に配置され、フラッシュからのものではないため、通常はフラッシュを占有しません。
変数を値で初期化することもできます。その場合、それらは初期化されたデータ セグメントに配置されるため、データ型のサイズに応じてフラッシュからスペースを占有します。
関数内の静的変数は、コードで初期化することもできます。その初期化は実行時に発生する必要がありますが、一度しか発生しないため、実際にはより多くのコードが生成され、ほとんどの場合、データのサイズよりも多くのスペースが必要になります (少なくとも、十分な大きさの構造体を関数の戻り値)。const 以外のグローバル変数についてもほぼ同じことができます。元は 0 で初期化されたままにしてmain()
、コードによる関数スコープの静的変数の初期化と同じスペースが必要な場所に(たとえば) 割り当てを配置するだけです。他の場所にかかります。
結論として、グローバル変数と関数スコープの静的変数の両方が同じ量のスペースを占有します。
上記は、埋め込みコンテキストの「グローバル変数」、またはファイルスコープの静的変数として想定しています。動的にリンク可能な実行可能ファイルでグローバル シンボルがエクスポートされる場合、そのシンボルの再配置情報は、実行可能バイナリでいくらかのスペースを占有します。ただし、システムの例が再配置可能な実行可能ファイルをサポートまたは使用しているとは思いません。
タイトルが示すように、FLASH (たとえば STM32 µC) でより多くのスペースを使用するのは何ですか? グローバル変数を宣言するか、関数内で静的変数を宣言しますか? それとも同じスペースを取りますか?
STM32 ビルドのリファレンスとして arm-none-eabi-gcc を使用すると、どちらもフラッシュ スペースをまったく使用しません。
宣言されていないグローバル変数と静的変数は、スタートアップの初期化が必要な場合はセクションconst
に入り、そうでない場合はセクションに入ります。これらのセグメントは両方とも、リンカー スクリプトによって SRAM に配置されます。C++ を実行している場合、静的 C++ クラスは..data
.bss
.bss
それらを宣言するとconst
、それらはセクションに配置されます。リンカースクリプトを参照すると、フラッシュ.rodata
にあるサブセクションに配置されていることがわかります。.text
フラッシュは通常、SRAM よりも豊富にあるため、可能な限り利用しconst
てください。
最後に、オプティマイザーが登場し、インライン化を優先してストレージを削除するなど、適切と思われるものを完全に再配置できます。