あなたの天然記念物
ホーム更新雑談Perl鉄ゲタランドナーコースガイド自転車Linuxリンク経歴連絡先

ROM変数 (2014.09.05)

初期値がある変数の初期化方法

リセット直後から関数mainに到着するまでにグローバル変数、スタティック変数を初期化しています。
  1. ROMに格納済みの初期値をRAMにコピーして変数とする
  2. 初期値を持たない変数はRAMをゼロクリアして変数とする
これで変数がRAMにできたので読み書きできます。 ところで、変数によっては初期値を参照するだけで更新しません。 でもコンパイラは変数は更新するのが前提で必ずRAMに確保します。 関数mainに到着した時点で初期値はROMと(コピーされた)RAMの2ヵ所にあります。 通常(constなし)は変数を更新するものですからRAMを参照、更新できて問題ありません。 ※ちなみにconstありもRAMにコピーします。 2014.09.05 訂正します。 const属性の変数はROMに配置されました。 あれ?なんで勘違いしたんだろう(汗)。 確認した処理系はRed Suite3 NXP Edition Full(512KB)Licenseです。 と言う訳でconstを前置すればこのページ自体不要です。 ただし、環境に左右されないプロジェクトを志向する人は、ソースにROM配置を記述できるので、書いても良さそうです。

参照専用の変数をROMに配置

参照だけのテーブルは更新できなくて良い訳ですから、初期値が格納済みのROMを参照すれば良いじゃないかと考えました。
まず、変数宣言用のマクロを用意、ROM変数専用のセクションへ配置させます。
// 参照限定のテーブルをROMに配置する属性
#define KSRK_ROM static const __attribute__((section(".ksrk_rom")))
次にリンカスクリプトでセクションを宣言しておきます。
	/* KSRK_ROM SECTION */	
	.ksrk_rom : ALIGN(4)
	{
		KEEP(*(.ksrk_rom))
		. = ALIGN(4);
		
	} > MFlash512
これで変数の宣言にKSRK_ROMを前置すればROMに配置されます。 当然ですけれど、ROM変数を更新しようとするとバスフォルトを食らいますからくれぐれもご注意ください。

図解

図解するとこんな感じ 変数の初期化

今回の鉄ゲタは…

当初、既存のセクション「.rodata」を指定してROMに配置させていましたけれど、 何故かProblemに警告が出てしまうので専用のセクション「.ksrk_rom」を用意しました。