スタートアップ時に割込みベクタをフラッシュからRAMにコピーする(ARM7)

テクニカル・ノート 27158

アーキテクチャ:

ARM

コンポーネント:

general

更新日:

2018/02/06 6:21

はじめに

このテクニカルノートでは、ARM7割り込みベクタをRAMに配置し、スタートアップコードで割り込みベクタを自動的に初期化する方法について説明します。

注意

シミュレータの使用

サンプルプロジェクト(27158.zip) は、シミュレータ用にビルドされ、デバッグされています。このテクニカルノートでは、起動時のベクタテーブルの初期化のメカニズムにフォーカスしているため、シミュレータで十分です。

シミュレートするデバイスのメモリマップの仮定

以下のメモリ領域を持つ

Flash at 0x1000000 to 0x100FFFF
RAM at 0x2000000 to 0x2007FFF
 

...スタートアップ時にフラッシュは以下領域にミラーリングされます...

0x0000000 to 0x000FFFF

...リマップ後、 RAM は以下領域にミラーリングされます...

0x0000000 to 0x0007FFF

リマップ (サンプルプロジェクトではカバーされていません)

異なるチップベンダのARMデバイスでは、異なる方法でリマップが行われるため、ここではリマップは扱いません。
理論的な前提 (このテクニカルノートとサンプルプロジェクトにおける) として、リマップは、初期化が行われる前の __low_level_init() 内で行われます。 

解決策

特別な解決策の理由

IAR ILINKリンカは通常、ベクタテーブルのコピー初期化用のコードを生成しません。ただし、IAR ILINKリンカに、ベクタテーブルを初期化する必要があることを通知することは可能です。

スタートアップ .s ファイルへの追加

必要な追加:

  • 2番目のベクタテーブル、つまりRAMに配置されるベクタテーブルを追加します。 (サンプルプロジェクトでは、RAMベクタテーブルは元のベクタテーブルのソースコードのコピーペーストに過ぎません)
  • このベクタテーブルを自身のセクションセクションに配置します。 (サンプルプロジェクトでは、このセクション名は .intvec_RAM です)
  • ベクタテーブルにラベルを追加します。 (サンプルプロジェクトでは、このテーブルは __vector_RAM です)
  • ベクタテーブルのラベルの上の行に特別なラベル __iar_init$$done: を追加します。 (このラベルは ILINK に、このベクターテーブルを立ち上げ時に初期化して良いことを知らせます。)

.icf fileへの追加

.icf ファイルの変更点は以下です:

define symbol _region_COPY_start__ = 0x00;
define symbol _region_COPY_end__ = 0x7F;
define region COPY_region = mem:[from _region_COPY_start__ to _region_COPY_end__];

initialize by copy { section .intvec_RAM };
define block RamCode { section .intvec_RAM };
define block RamCodeInit { section .intvec_RAM_init };
place in ROM_region { block RamCodeInit };
place in COPY_region { block RamCode };

詳細:

  • 以下行は、コピーが行われる領域を定義するために追加されます。
    define symbol _region_COPY_start__ = 0x00;
    define symbol _region_COPY_end__ = 0x7F;
    define region COPY_region = mem:[from _region_COPY_start__ to _region_COPY_end__];
  • 以下行は、ILINK に、このセクションは初期化されることを知らせます。
    initialize by copy { section .intvec_RAM };
  • 以下行では セクション .intvec_RAM_init はILINK に、文字列の最後に _init があることで、このブロックが .intvec_RAM のコピーを(フラッシュ内に)持っていることを知らせています。
    define block RamCodeInit { section .intvec_RAM_init };
  • .icfファイルの最後の変更は、IAR ILINKリンカが、RAM内の割り込みベクタを上書きしないように、RAMおよびフラッシュメモリの先頭0x80バイトに'通常の'データ/コードを配置しない用に編集します。 スタートアドレスは次のように調整されます。
    define symbol __ICFEDIT_region_ROM_start__ = 0x1000080;
    define symbol __ICFEDIT_region_RAM_start__ = 0x2000080;

サンプルプロジェクトを動作させる

ビルド

IAR Embedded Workbench のすべてのエディタタブを閉じて、プロジェクトを再ビルドします。

デバッグセッション開始

C-SPYを開始します。 アプリケーションはラベル __iar_program_start で停止します: これは、メモリウィンドウで0x00番地以降のメモリがすべてゼロであることを確認できるように意図的なものです。

実行

アプリケーションは、main() で停止します。そこにはブレークポイントがあります。ここでは、0x00番地以降にコピーされたベクタテーブルがあることがメモリウィンドウからわかります。

全ての製品名は、それぞれの所有者の商標または登録商標です

申し訳ございませんが、弊社サイトではInternet Explorerをサポートしていません。サイトをより快適にご利用いただくために、Chrome、Edge、Firefoxなどの最新ブラウザをお使いいただきますようお願いいたします。