位置独立コード・データ (ROPI と RWPI)
テクニカル・ノート 90935
アーキテクチャ:
ARM
コンポーネント:
compiler
更新日:
2018/09/04 7:47
はじめに
バージョン5.50以降のIAR Embedded Workbench for ARMは、オプションで位置独立コードおよび/または位置独立データを生成できます。
定義
- ROPI = Read-Only Position Independence(リードオンリー位置独立) リンカから出力される「リードオンリー ELF 出力」の全てに関連します。これは定数データとデーターの初期化データを含みます。すなわち、通常 FLASH に入るもの全てです。
- RWPI = Read-Write Position Independence(リードライト位置独立) リンカから出力される「リードライト ELF 出力」の全てに関連します。
- 現在のバージョンでは --pi_veneers (位置独立べニア) オプションも有効です。詳細は C/C++開発ガイドをご参照ください。
コンパイラオプション
以下は C/C++開発ガイドからの抜粋です。
- オプション: --ropi
このオプションは PC相対参照でコード/リードオンリーデータをアクセスする場合に使用します。
このオプションを使用すると以下の制約が生じます:
* C++ の構造を使用することはできません
* オブジェクト属性 __ramfunc が使用できません
* ポインタ定数は、他の定数、ストリングリテラル、関数のアドレスで初期化することができません
但し、静的な書き込み可能変数はランタイムに、書き込み可能な可変アドレスで初期化することができます
--no_rw_dynamic_init (下記) と プリプロセッサシンボル __ROPI__ も参照してください。 - オプション: --rwpi
このオプションは、スタティックベースレジスタ (R9) からのオフセットで書き込み可能なデータにアクセスするコードを、コンパイラに生成させます。
このオプションを使用すると以下の制約が生じます:
* オブジェクト属性 __ramfunc が使用できません
* ポインタ定数は、他の定数、ストリングリテラル、関数のアドレスで初期化することができません
但し、静的な書き込み可能変数はランタイムに、書き込み可能な可変アドレスで初期化することができます。
--no_rw_dynamic_init (下記) と プリプロセッサシンボル __RWPI__ も参照してください。 - オプション: --no_rw_dynamic_init
このオプションは、静的 C変数のランタイム初期化を禁止します。--ropi または --rwpi でコンパイルされた Cソースコードは、リンク時点で、アドレスが決まっていないオブジェクトのアドレスを初期化する、静的なポインタ変数または定数を持つことができません。書き込み可能な静的変数の、この問題を解決するため、コンパイラは立ち上げ時、C++の動的初期化と同じやり方の初期化を行うコードを生成します。
サンプルプロジェクト
ROPI/RWPI が必要な各プロジェクトでは、アプリケーションの設計、開発、およびデバッグ環境はユニークです。多くの異なるユースケースと位置独立コード/データの必要性は予測困難です。
あらゆる側面をカバーするサンプルを作成することは難しいのですが、ここに、簡単な ROPI と RWPI の例を示します。
サンプルプロジェクトをダウンロード して、 readme.pdf に書かれている指示に従いビルド・実行してください。 STM32F4 Discovery board exampleもあります。
注意:
IAR Embedded Workbench for ARMの新しいバージョンでエラーになった場合は、
static __global_reg char* rwpi_data @ "R9";
を
#if (__VER__ < 6020000)
static __global_reg char* rwpi_data @ "R9";
#else
static __no_init char* rwpi_data @ R9;
#endif
に書き直してください。
全ての製品名は、それぞれの所有者の商標または登録商標です