背景
前回、STM32F407のCCMRAMを使うを投稿し、無事CCRAMを使うことができました。
めでたし、めでたし...と思いきや、由々しき状況に気づきました。
CCMRAM上に不定の初期値をゼロフィルするセクションbbbを作ったのですが、なんとLoad addressの欄に内蔵フラッシュのアドレスが記載されています。
どうやら初期値付きの変数として認識されているようです。
初期値を確める
確認のため、0x08014c90のフラッシュの中身を見てみます。
0x08014c90以降がCCMRAM上の変数の初期値として0が内蔵フラッシュに書き込まれていました。
しかも、アセンブラのスタートアップではこのエリアのデータを使わず、CCMRAMをゼロフィルしているので、使わないデータが内蔵フラッシュに鎮座しているということです。
プログラムの動作に影響はありません...だから気づくのにも時間がかかりました。
リンカスクリプトではフラッシュに初期化データを置くような書き方はしていません...
.ccmram :
{
. = ALIGN(4);
_sccmram = .; /* create a global symbol at ccmram start */
*(.ccmram)
*(.ccmram*)
. = ALIGN(4);
_eccmram = .; /* create a global symbol at ccmram end */
} >CCMRAM AT> FLASH
.bbb :
{
/* This is used by the startup in order to initialize the .bss section */
_sbbb = .; /* define a global symbol at bss start */
__bbb_start__ = _sbbb;
*(.bbb)
*(.bbb*)
. = ALIGN(4);
_ebbb = .; /* define a global symbol at bss end */
__bbb_end__ = _ebbb;
} >CCMRAM
初期値付きのセクションは、>CCMRAM AT> FLASH
としており、スタートアップでゼロフィルするセクションは>CCMRAM
と記載しています。
これがうまく効いてないみたいです。
答えはこちら...
答えに辿り着くのは大変でした...
STのコミュニティサイトで解決策が見つかりました!
Prevent zero-initialized arrays in CCMRAM from being stored in FLASH.
.bbb(NOLOAD) :
{
/* This is used by the startup in order to initialize the .bss section */
_sbbb = .; /* define a global symbol at bss start */
__bbb_start__ = _sbbb;
*(.bbb)
*(.bbb*)
. = ALIGN(4);
_ebbb = .; /* define a global symbol at bss end */
__bbb_end__ = _ebbb;
} >CCMRAM
早速(NOLOAD)
を追記してコンパイル〜リンクしてみます。
このように、Load addressの欄は空欄になり、初期値は不定という設定にできるので、あとはスタートアップでゼロフィルすればOKです。
いやぁ、ここまで来るのに時間がかかりましたが、これでスッキリしました。