プログラムのコンパイル (執筆中)

!!! プログラムでの実験待ち

!!! プログラムソースの取り込み待ち

組み込み系コンパイルの特徴

組み込み系環境では、使う CPU、基板によって搭載されているメモリ容量が異なっていたり、電源投入後の CPU の挙動が CPU の種類によって異なっていることがあります。例えば、同じ SH7045F を使用していても、外部 RAM 領域が 1M のものと、256K とでは異なりますし、同じ容量の外部 RAM を搭載していても、バスアクセス時のウェイトサイクルが異なることもあります。
このように、組み込み系では、プログラムが動作する環境はプログラム毎に異なっている可能性があるため、main 関数が含まれるプログラムの他に、リンカスクリプトやスタートアップルーチンをプログラムと一緒にコンパイルします。

以降で、サンプルを示しながら少し詳しく説明します。

リンカスクリプト

リンカスクリプトでは、スタートアップルーチンで使うシンボルやメモリ構成の定義を行っています。例えば、同じ CPU を用いる場合でも基板毎に搭載している ROM, RAM 容量が異なる可能性がありますが、リンカスクリプトはプログラムが動作する CPU の ROM, RAM 容量を定義したり、プログラムをどの領域に配置すべきかといった定義を記述をします。
それでは、実際のリンカスクリプトを示しながら説明していきます。

リンカスクリプト

リンカスクリプトの具体例は以下のようになります。

!!! ファイルの include

メモリ構成の定義

!!! 説明

スタートアップルーチンで用いるラベルの定義

!!! 説明

ベクタテーブル用の記述

!!! 説明

スタートアップルーチン

CPU に電源を入れたときの起動手順は、CPU の種類によって異なる。SH2 の場合は、仕様書の「例外処理」の章で定義してある通り、0x00000000 番地に格納されているアドレスからプログラムが実行される。 このような最初に実行すべき処理はスタートアップルーチンと呼ばれ、アセンブリ命令のコマンドで初期化処理を記述しなければならないこともある。例えば、SH2 シリーズにおける割り込みベクタアドレスの登録は ldc というアセンブリ命令で処理される。 従って、スタートアップルーチンは通常アセンブリ言語で実装され、main 関数が呼ばれる前に実行すべき処理を行うことになる。そのような処理としては、以下の挙げる項目がありうる。

この様な処理を行う SH7045F 用のスタートアップルーチン例を以下に示す。

!!! crt0.S の include

以下で、スタートアップルーチンの中での処理について詳説する。

バスの初期化

!!! 説明

ベクタテーブルの初期化

!!! 説明

スタック領域の初期化

!!! 説明

変数領域の初期化

!!! 説明

main() の呼び出し

!!! 説明

プログラムのコンパイル

最終的に、プログラムはリンカスクリプト、スタートアップルーチン、main() を含むソースコード、を指定してコンパイルされなければならない。クロスコンパイラの構築 で構築した SuperH 用 gcc である sh-coff-gcc コマンドを用いると、そのコマンドは以下のようになる。

% sh-coff-gcc ... 

つまり、-T にてリンカスクリプトを指定し、必要なオブジェクトファイル(*.o) を一緒にコンパイルすることで、リンカスクリプトの情報が反映された CPU 上で実行可能なプログラムが生成される。

Makefile の利用

通常のコンパイル手順を Makefile を用いて記述するように、クロスコンパイルの処理も Makefile で記述できると便利である。以下に、モトローラ S-format 形式のファイル(mot)や、実行ファイルを逆アセンブルしたもの(dis)、ROM に焼き込むためのアドレス配置の mot ファイル(rom) を出力するような Makefile 用の定義ファイルを記述した例を示す。

!!! sh_rules.mk の include

クロスコンパイルを伴うディレクトリの Makefile では、以下のように sh_rules.mk を include して用いることになる。

!!! Makefile より抜粋

以上で、SuperH 用のクロスコンパイラを用いてプログラムをコンパイルする手順を説明を終わる。

Generated on Mon Apr 13 22:52:06 2009 by  doxygen 1.5.7.1