SH-2 CPU 備忘録


 ■7.SH-2 プログラミング その2 アルファプロジェクトボード編

○アルファプロジェクト
 組み込みボードの総合メーカアルファプロジェクトのSH2CPUボード使用の場合、環境の整備には大まかに分けて、2つの方法があります。アルファプロジェクトのHPはこちら  アルファプロジェクトのStarterKitを購入すると、ソフトのみならず、書き込み用ツールのハードやソフト、その他ドキュメントとサポートさらにVMonitorというデバッグ環境も付いていきます。1度に苦労なく環境を揃えられて便利です。また、ボードのみの購入でも、そのCPUボード対応の書き込み用ソフト「F-ZTAT書き込みソフト」が付属しています。
 KPIT GNU Toolsは基本的にフリーですが、書き込みツールはありません。まあ、SHCPUをIC単体で購入し、基板から自前で作ったのなら別ですが、通常ボードの形で購入すると思うので、各ボードメーカーが何らかのコンパイラ環境や書き込みツールを用意していると思うので、これを使うのが常道でしょう。ボードメーカーとしては他に秋月電子通商などがあります。
 さらに、書き込みソフトに関しては、CQ出版のインターフェイス誌2006年6月号付録CD-ROMにFDTが付いています。詳しくは インターフェイス誌バックナンバーを見てください。
○コンパイラのダウンロード
 コンパイラのダウンロードについては、6.SH-2 プログラミング その1 GNUSH編をごらんください。ここでは、アルファプロジェクト提供のStarterKit内のGunuProコンパイラで解説してゆきます。
○Kit付属のコンパイラのインストール
 Kit付属のマニュアル「コンパイラ編」をご覧ください。またインストール方はGnuSHとほぼおなじなので、それでよければこちらをご覧ください。
○ソースの用意
 以下のファイルがアルファプロジェクトのボード同梱のFDD内にサンプルとして入っています。
 この中で、ソースファイルは「7046s.h」・「crt0.s」・「main.c」・「vector.s」・「sci.c」です。また、「makefile」はmakeコマンドを実行する為に必要で、このコマンドを使うと、変更のあったソースファイルのみコンパイルしリンクしますので、大規模なソースのコンパイルでは、時間短縮になります。
○main関数から実行しない
 SH2CPUは、ハーバードアーキティクチャーを採用しています。通常のパソコンで使われるインテル系のCPUはノイマン型のアーキティクチャーです。このCPUの場合は、プログラムとデータは分け隔て無く同じメモリー上に混在して存在しています。一方、SH2CPUの場合FLASHROMにプログラムを書き込む訳なのですが、CPU動作時は一応ROMなので、データの書き込みは出来ません。C言語の変数などは、このためRAM領域にCPU起動時に配置することとなります。初期値がある変数などは、一端FLASHROM領域に書き込み、CPU起動時にRAM領域に転送する処理が必要となります。また、割り込みベクターなどの設定も必要な為、main関数の実行前に色々と行わなければならない処理がアセンブラ等で書かれています。
 「crt0.s」からCPUは実行を始め、そこには、スタック領域の設定と、次に実行するのは「main.c」内の「boot」の部分を実行するよう書かれています。スタック領域や前述の変数領域の設定は、「sh2f_4a.x」ファイルに書かれています。「boot」関数では、モジュールスタンバイレジスタの設定やIOポート設定を行い、「sectionInit」関数に実行が移ります。「sectionInit」関数では、ROM領域から必要なデータのRAM領域への転送を行い。これが終わって初めて、「main」関数が実行されます。
/* crt0.s */

	.section	.text

	.extern		_boot
	.global		_start

_start:
	mov.l		L_BOOT,r8
	jmp		@r8
	nop

	.align		4
L_BOOT:			.long	_boot

	.section	.stack
	.global		_stack
	.align		4
_stack:			.long	1

	.end
/*	セクション初期化				*/
extern char etext, sdata, edata, bss_start, end;
void sectionInit()
{
	char	*src;
	char	*dst;

	/*	初期化データ領域	*/
	src	= &etext;
	dst	= &sdata;
	while (dst < &edata) {
		*dst++	= *src++;
	}
	/*	未初期化データ領域	*/
	for ( dst = &bss_start; dst < &end; dst++ ) {
		*dst = 0;
	}
}
○サンプルのコンパイル
 makefileがあると至極簡単です。GunuProコンパイラがインストール済みであれば、「スタートメニュー」から「すべてのプログラム」→「Cygnus」→「Cygnus GNUPro ToolKit...」を選択します。すると、DOSプロンプトのCygnus環境が起動します。起動したら、sampleフォルダーに移動して、makeコマンドを入力します。
C:\cygnus\sample>make
sh-hms-gcc -c -v -O0 -m2 main.c -o main.o
    … 中略 …
cc.a)_sdivsi3.o
sh-hms-objcopy -O srec sh2f_4a.out sh2f_4a.mot

C:\cygnus\sample>
sh2f_4a.motファイルが出来たら、コンパイル成功です。途中エラー表示がでたら、修正します。
よく出るエラー表示の例(;の付け忘れ)。エラー行の近辺を問題がないか見てみる。
main.c: In function `boot':
main.c:79: parse error before `}'
main.c:95: `data' undeclared (first use in this function)
main.c:95: (Each undeclared identifier is reported only once
main.c:95: for each function it appears in.)
main.c:98: warning: `return' with a value, in function returning void
make: *** [main.o] Error 1

C:\cygnus\sample>
○効率よいプログラムを作る
 SH2CPUは32bitCPUです。「そんなのわかっているわい」という声が聞こえてきそうですが、これは一番高速に扱える局所変数の型は何型かというと4バイト(32bit)の変数の型です。つまりint型です。他の型は1度にレジスタに読み込めず、せっかくのRISC命令が複数必要になってしまいます。また、符号なしと符号付きでは、符号付きが効率がいいです。これは符号付きが標準だからです。
 また、アセンブラをやった方なら分かると思いますが、変数はメモリーに格納されていますが、変数を参照するということは、メモリーへアクセスするということです。ですので、大域変数がいくつかあるときは、構造体にして、小さい順に宣言して、構造体のアドレスのポインターを用いてアクセスすると効率よくメモリー参照ができます。とはいえ、最初から気張ってやっていると大変ですから、まずは自分のスタイルで書き始めて、だんだんこのことを考えながら改良してゆけばよいと思います。
suruct aaa {
    signed char a;
    short       b;
    int         c;
} a;

void main(void)
{
    struct aaa *pp = &a;
    
    pp->c = pp->a + pp->b;
}



TOPへ戻る
SH2 CPU Programinng for alpha project cpubord ap-sh2f_4a. 2006.05.23 First Edition.