« | »

2008.05.07

こんにちはH8の世界

H8マイコンで動く”Hello, world!”を作ってみます。

ここで紹介するのは、以前に公開したh8monが書き込まれているAKI-H8/3069Fマイコンボードで動作するものです。

とは言ってもOSも無ければ標準出力も無い環境です。とりあえず出力はh8monでもコンソール入出力に使っているRS232Cで行うこととします。

方法としては直接SCI1(RS232C)を制御してアスキーコード文字列を出力することが考えられますが、以下のようなソース(hello.c)でも文字を出力することが出来ます。

void putch(char ch)
{
asm("mov.l	#0, er2");
asm("trapa	#2");
}
static void print(char *str)
{
while(*str) {
putch(*str);
str ++;
}
}
int main(void)
{
print("Hello, H8 world!\r\n");
return 0;
}

このソースだけではまだ実行は出来ません。スタートアッププログラムが必要なのですが、まずはmain()を解説します。

printf()のような標準入出力関数は(使う方法はあるのですが)使えません。printf()の代わりの文字列出力関数としてprint()を書きました。中は文字列の終わり(0)まで一文字づつputch()に引数として渡しているだけです。

putch()の中身はインラインアセンブラで書かれています。
内容はer2レジスタを0にして、「trapa #2」を実行しています。

実はh8monではtrapa #2でSCI1から文字を入出力することが出来ます。er2を0にするとer0に書かれたデータが出力されます。er2を1にするとSCI1が受信したデータをer0に書き込みます。つまり戻り値として参照できます。
(このコードはあまり良い例ではありません。このコードは引数がer0で渡されて、他のレジスタが破壊されないことを期待しています。実際にそうなるのですが、本来は「拡張アセンブリ構文」を使うべきです。今回はソースの見易さを優先してこのようにしています。)

以下はスタートアップルーチン(start.s)です。

	.h8300h
.section .text
.global	_start
.extern	_stack_bottom
.extern _bss_start
.extern _bss_end
_start:
;	mov.l	#0x600000,er7		; Set SP
mov.l	er0,@-er7
mov.l	er1,@-er7
;; .data section initialize
mov.l	#_dataRAM_start,er0
mov.l	#_dataRAM_end,er1
mov.l	#_dataROM_start,er2
bra	loop11
loop1:
mov.l	@er2,er3
mov.l	er3,@er0
add	#4,er0
add	#4,er2
loop11:
cmp.l	er0,er1
bf	loop1
;; .bss section initialize
mov.l	#_bss_start,er0
mov.l	#_bss_end,er1
mov.l	#0,er2
bra	loop21
loop2:
mov.l	er2,@er0
add	#4,er0
loop21:
cmp.l	er0,er1
bf	loop2
mov.l	@er7+,er1
mov.l	@er7+,er0
jsr	_main		; Goto main()
;	rts
trapa #3
.end

各セクションを初期化してmain()をコールしています。最後の「trapa #3」はh8monに処理を戻すための物です。h8monではソフトウェアブレークとしてtrapa #3を使用しています。スタックポインタ(er7)の初期化も必要なのですが、上記ではコメントにしています。この場合、スタックポインタはh8monが設定する初期値(0xFFFF20:内蔵SRAM)で動作します。

以下はリンクスクリプト(h83069.lds)です。

OUTPUT_FORMAT("elf32-h8300")
OUTPUT_ARCH(h8300h)
ENTRY("_start")
MEMORY
{
ram(rx)		: o = 0x400000, l = 0x080000
}
SECTIONS
{
.text :	{
*(.text)
*(.strings)
*(.rodata)
*(.rodata.str1.1)
_dataROM_start = . ;
} > ram
.data ALIGN(4) : {
_dataRAM_start = . ;
*(.data)
_dataRAM_end = . ;
} > ram
.bss ALIGN(4) : {
_bss_start = . ;
*(.bss)
*(COMMON)
_bss_end = . ;
} > ram
}

プログラムを0x400000番地に配置するようにしています。この番地にはAKI-H8/3069FマイコンボードではDRAMが実装されています。h8monでは起動後、DRAMが使用できるようにBSC(バスコントローラ)を初期化しています。

最後にMakefileです。

CROSS   = h8300-elf-
CC	= $(CROSS)gcc
AS	= $(CROSS)as
LD	= $(CROSS)gcc
OBJCOPY	= $(CROSS)objcopy
CFLAGS	= -mh -g -O2 -Wall
LDSCRIPT= h83069.lds
LDFLAGS = -mh -Wl,-Map,$*.map -Wl,-T$(LDSCRIPT) -nostartfiles
PROGRAM	= hello.mot
OBJS          = start.o hello.o
SRCS          = start.s hello.c
.SUFFIXES:	.mot .exe .a .o .c .s .h
.c.o:
$(CC) $(CFLAGS) -c $<
.elf.mot:
$(OBJCOPY) -Osrec $< $@
all: $(PROGRAM)
$(PROGRAM): $(OBJS) $(START) $(LDSCRIPT) $(DEPEND)
$(LD) $(LDFLAGS) -o $*.elf $(START) $(OBJS) -lgcc
$(OBJCOPY) -Osrec $*.elf $*.mot
clean:
rm -f -r $(OBJS) $(PROGRAM) $(DEPEND) *.mot *.map *.elf *~

以前紹介したクロスコンパイラでコンパイルできます。

makeコマンドでコンパイルすると「hello.mot」が出来るはずです。

h8monでは「l」コマンドでhello.motをロードすることが出来ます。ターミナルソフトは「Tera Term Pro」がおすすめです。h8monでlコマンド入力後、「ファイル送信」機能かhello.motファイルをドロップして転送します。

h8monのgコマンドでロードしたプログラムを実行します。

実際に動かした画面は以下のようになります。

H8/300(H) 3069F Monitor Ver. 0.80
(c)2003,2004,2007 Takashi SHUDO
Virtual vector table area : FFBF20 - FFC01F
Monitor used RAM area     : FFC020 - FFC475
Monitor stack end address : FFC608
Build date                : 11:27:06 May  3 2008
>l
Please send S-records data.
Load address     : 400000 - 4000B2
Excution address : 400000
Done.
>g
Hello, H8 world!
Break.
PC = 400062      CCR = 84
R0 = 00FF0000    R1 = 00FFC090   R2 = 00FFC0F0   R3 = 00FFC09D
R4 = 00000000    R5 = 00000000   R6 = 00000000   R7 = 00FFFF20
400062 : 57 30                         trapa    #0x3:3
>

「Hello, H8 world!」の文字が出力されています。今回のソースはここに置いておきます。

ここまで読んでくれた方、お疲れ様でした。次回はh8monの目玉?である、gdbを使ったソフトの実行、デバッグを予定しています。(いつになったは工作の話になるんだろう(^^;;;)

Trackback URL

Comment & Trackback

No comments.

Comment feed

Comment





XHTML: You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>