適用先: ARM 開発ツール
回答
このナレッジ記事に含まれている情報の適用先:
- MDK-ARM
現象
初期化したくないメモリのセクションがあり、スキャッタファイル内で、そのメモリ領域を UNINIT とマークしました。変数を領域 UNINITとして配置するために、__attribute__((section(""))) を使用しています。
。 スキャッタ ファイル:
LR_IROM1 0x08000000 0x00080000 { ; load region size_region ER_IROM1 0x08000000 0x00080000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } RW_IRAM1 0x20000000 UNINIT 0x00000100 { ;no init section *(NoInit) } RW_IRAM2 0x20000100 0x0000FFF0 { ;all other rw data .ANY(+RW +ZI) } }
C コード:
unsigned long NI_longVar __attribute__( ( section( "NoInit")) ) ;
int main( void ) { while( 1 ) { } }
変数は領域 UNINIT 内に正しく配置されていますが、変数のメモリ内容は初期化されたままです。まるでスキャッタファイル内の UNINIT タグが無視されているかのようです。なぜでしょうか?
原因
最適化上の理由により、8 バイト以下のグローバル ZI 変数は RW データ セクション内に配置されます。
UNINIT セクション内の ZI データだけは初期化されないままですが、UNINIT セクション内の RW データは初期化されます。上記のコード例の変数は 8 バイト未満であるため、ZI データから RW に変更されています。これが原因で初期化が実行されます。
解決策
最適化を阻止するために、zero_init 属性を変数に追加します。これにより、変数は初期化されず ZI データのままになります。
unsigned long NI_longVar __attribute__( ( section( "NoInit"),zero_init) ) ;
フォーラムのスレッド
下記の Discussion Forum のスレッドで本件に関連する情報が提供されている可能性があります。