現在は AKI-H8 キットに 1Mbit SRAM と LCD表示器、およびボタンを接続して、 日立のフリーモニタを搭載して単体でモニタが起動し、gdb を使ってリモート デバッグができるようになっています。さらに、RTOS も動作しています。
今回は普段自分が使用している FreeBSD(-2.2.6RELEASE) で環境を作成します。
プラットフォームに依存する内容はわずかなので、linux など、
別の OS でも構築は難しく無いはずです。
クロスCコンパイラを作るためには次のものが必要です。
適当な ftp サイトや、CD-ROM から入手してください。
一連の作業のために必要なディスク容量はコンパイルに 150MB 程度、
インストール先に 20MB 程度です。
まずは基本的な構築をおこなってから、それから各ツールについて
AKI-H8 用の変更、移植を行って行きます。
シミュレータデバッグ時の手順をまとめると
ブレークポイントの設定の仕方、ソースデバッグの方法は通常の gdb の使い方
と同じです。
接続は簡単です。データ、アドレスラインは1対1に、CS2 は RES(CN2-4)に
-CS は P8-3/-CS1(CN1-6)に -WEは P6-5/HWR(CN2-8)に -RDは P6-4/-RD(CN2-7)に
結線するだけです。
同様に LCD 表示器を接続しました。接続は PortB で D0〜D7 を、
PortA-7 が RS、PortA-6 が E 、R/W はGND固定にしました。
電源をいれると 「Welcome!!」と表示してくれます :-)
128KByte の SRAM 空間をフルに使用することにします。全てRAM空間ですので
順に先頭からベクタ、コード、データと割り振りました。今回定義した例を
次に示します。
次のように使います。
調べるとソースがおかしい部分があったので、修正します。
このパッチ(srecfix.diff.gz[231bytes])
を binutils-2.8.1/bfd/srec.c に対して当てて、binutils を make
、make install しなおしてください(オブジェクトの最終アドレスが
16bit 以内で表現できれば S1, 24bit ならば S2, それ以上だと S3 となる
コードのようですが、S2 となる条件の評価が間違っているので S3 と判断
してしまいます)。
FreeBSD には標準でインストールされていないので自分でインストールします。
インストール手順は簡単です。
終了する時は Ctrl-\, Ctrl-C でプロンプトに戻り q (quit) とすれば
終了します。
gdb には hms のモニタ用のリモートデバッグ機能が標準で組み込まれています。
しかし、これはそのまま今回使用している日立のモニタに対応していません。
そこで、この hms 用のリモートデバッグ機能の部分を日立のモニタ用に改造
しました。
改造は最初のころ非常に難しいと思っていましたが、gdb のリモートデバッグ機能は
最初からいろいろなモニタに対応できるような仕組みが用意されていて、
その動作が分かってしまったら、以外と簡単にできました。
次の手順で gdb を作り直してください。
次のようなサンプルプログラムを用意します。
シミュレータの時は target に sim を指定しましたが、
今回は hms を指定します。
シリアルポートで接続するので、デバイスとシリアルスピードの指定も行います。
この時 H8 側は電源をいれてモニタが起動している状態にしておいてください。
実際に動かした時の様子を次に示します。
準備
ここでは作成した環境は全て
/usr/local/cross
の下に置く物とします。
また、のちの作業で使うので、次の物も一緒に用意しておきます。
さらに GNU make (gmake-3.76.1)もインストールしておいてください。
GNU make でないと newlib と gdb のコンパイルに失敗します
(以下の作業では GNU make を gmake としています)。
まずバイナリユーティリティーを作成します
行う作業は非常に簡単です。target に h8300-hms を指定して configure します。
(hms は「Hitachi Micro Systems」から来ているようです。)
以上でアセンブラやリンカ、オブジェクト操作ツール類が用意できました。
cd [workdir]
tar xvfz [somewhere]/binutils-2.8.1.tar.gz
cd binutils-2.8.1
./configure --target=h8300-hms --prefix=/usr/local/cross
gmake CFLAGS=""
gmake install
次にCコンパイラを作成します
次にCコンパイラ本体を作成します。基本的には binutils の構築方法と一緒です。
cd [workdir]
tar xvfz [somewhere]/gcc-2.7.2.3.tar.gz
cd gcc-2.7.2.3
このパッチは libgcc2 で eprintf のコンパイルエラーを防ぐ対策と、
H8 での float の定義を行っています。
パッチが入手できなくても、float は特に使わないし、
コンパイルが通ればいいのであれば、configure の作業後、
Makefile の LIBGCC_CFLAGS に -Dinhibit_libc を追加すれば
コンパイルできます。
patch -p1 < [somewhere]/crossgcc-gcc-2.7.2.2.patch
これをしないとリンク時にエラーとなります(FreeBSD で構築する時のみ必要です)。
CLIB=-lgnumalloc
./configure --target=h8300-hms --prefix=/usr/local/cross
gmake LANGUAGES="c" CFLAGS="-O2"
gmake install LANGUAGES="c"
標準Cライブラリ newlib のコンパイル
C の標準ライブラリを作成します。ターゲットマシン用のライブラリですので、
これまでに作成した gcc を使用します。
実行パスに /usr/local/cross/bin を追加し、コンパイラが起動できるように
した上で次の作業を行います。また GNU make を使ってください。
cd [workdir]
tar xvfz [somewhere]/newlib-1.8.0.tar.gz
cd newlib-1.8.0
./configure --target=h8300-hms --prefix=/usr/local/cross
gmake
gmake install
gdb のコンパイル
ソースデバッガを作成します。H8 にはシミュレータが用意されています。
ですので、作成したプログラムの部分的なデバッグには非常に有効です。
H8(-mh)用の修正が gdb-4.16 から gdb-4.17 の間で行われているので、
gdb-4.16 ではなく gdb-4.17 を用意してください。
また GNU make でないとコンパイルの途中で失敗します。
以上でGNUのクロス開発環境の基本的な部分の作業は終りです。
cd [workdir]
tar xvfz [somewhere]/gdb-4.17.tar.gz
cd gdb-4.17
./configure --target=h8300-hms --prefix=/usr/local/cross
gmake
gmake install
できた環境を使ってみる
まずはシミュレータを使って動かして見ましょう。
/usr/local/cross/bin をサーチパスに加えてください。
簡単なサンプルソース
次のようなサンプルを用意しました。
H8 用なのに printf ?と気づかれた方もいると思います。でも気にしないで
先に進みましょう。
hello.c:
#include < stdio.h>
int main()
{
int i;
for (i = 0; i < 10; i++){
printf("<%d> Hello World!\n", i);
}
}
コンパイルします
h8300-hms-gcc -o hello -g -mh hello.c
ここで -g と -o についての説明の必要は無いでしょう。
-mh は H8/300H 用のコードを生成するオプションです。
これを付けない時は H8/300 用のコードを作ってしまうので
忘れずに付けてください。
gdb のシミュレータ上で実行します
今作成したオブジェクトを gdb のシミュレータで動かします。
実際に動かした時の様子を次に示します。
動きましたか?さらに printf の結果も出力されています。
% h8300-hms-gdb hello
GNU gdb 4.17
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "--host=i386-unknown-freebsd2.2.6 --target=h8300-hms"...
(gdb) set machine h8300h
(gdb) target sim
Connected to the simulator.
(gdb) load
Loading section .text, size 0x7382 lma 0x100
Loading section .data, size 0x2b8 lma 0x7482
Loading section .stack, size 0x4 lma 0x3fffc
Start address 0x100
Transfer rate: 242160 bits in <1 sec.
(gdb) run
Starting program: /tmp/hello
<0> Hello World!
<1> Hello World!
<2> Hello World!
<3> Hello World!
<4> Hello World!
<5> Hello World!
<6> Hello World!
<7> Hello World!
<8> Hello World!
<9> Hello World!
Program received signal SIGTRAP, Trace/breakpoint trap.
0x56c in _exit (rc=4352) at _exit.c:14
_exit.c:14: No such file or directory.
(gdb)
最初に set machine h8300h を実行するのを忘れないでください。
まとめ
コンパイル時に注意するのは
です。
です。
クロス開発時には次のコマンドも覚えておくと良いでしょう。
詳しく知りたい方は gdb の info などをお読みください。
日立のモニタ用に環境をいじる
メモリ増設とLCD接続
GNU C でちょっとしたプログラムを作成し、
モニタを使ってメモリ上でデバッグすると H8/3048 本体の 4KB のメモリでは
小さすぎて思うようなプログラムが作れません。
そこで 1MBit の SRAM メモリ(HM628128)を増設しました。
あとは CN5 でモード5 に設定し、モニタの起動時各ポートのモードを設定する
コードを追加すればモニタから使えるようになります。
実際の設定は次のようにしました。
そして、仮想ベクタ空間を SRAM の先頭番地から配置しました。
こちらもモニタ起動時にポートおよび LCD の初期化のコードを追加しました。
メモリ配置を定義
こんどは SRAM 空間でコンパイルしたプログラムが動作するように、
リンカのアドレス定義を変更します。デフォルトの定義は
/usr/local/cross/h8300-hms/lib/ldscripts/h8300h.x
にされています。
ld に -T オプションで指定すること(gcc には -Wl,-T)で、上のメモリ配置で
オブジェクトを作成してくれます。
OUTPUT_FORMAT("coff-h8300")
OUTPUT_ARCH(h8300h)
ENTRY("_start")
MEMORY
{
/* 0xc4 is a magic entry. We should have the linker just
skip over it one day... */
vectors : o = 0x20000, l = 0x100
ram : o = 0x020100, l = 0x1fefc
stack : o = 0x03fffc, l = 0x4 /* 0x20000 - 0x3ffff */
}
SECTIONS
{
.vectors : {
/* Use something like this to place a specific function's address
into the vector table.
SHORT(ABSOLUTE(_foobar)) */
*(.vectors)
} > vectors
.text : {
*(.rodata)
*(.text)
*(.strings)
_etext = . ;
} > ram
.tors : {
___ctors = . ;
*(.ctors)
___ctors_end = . ;
___dtors = . ;
*(.dtors)
___dtors_end = . ;
} > ram
.data : {
*(.data)
*(.tiny)
_edata = . ;
} > ram
.bss : {
_bss_start = . ;
*(.bss)
*(COMMON)
_end = . ;
} >ram
.stack : {
_stack = . ;
*(.stack)
} > stack
}
gcc -mh -o hello.coff -Wl,-T[scriptfile] hello.c
Sフォーマットレコードに変換
作成したオブジェクトをモニタにロードするために Sレコードフォーマットに
変換します。リンカで直接 Sレコードを出力することができますが、
(後の)ソースデバッグの事を考えて、リンカ側で対処せず、objcopy ツール
を使用します。
これで Sレコードファイルができます。
h8300-hms-objcopy -Osrec 作成オブジェクト Sレコードファイル
binutils S2 フォーマットに変換できない問題を修正
objcopy で作成された Sレコードは前述のメモリ配置
の状態のオブジェクトを変換すると S3 フォーマットで出力します。
実は日立のフリーモニタはこの S3 フォーマットを理解してくれません
(Sフォーマットの詳細は各自で調べてください)。
配置アドレスからすると S2 フォーマットで十分のはずです。
これで objcopy で前述の手順で変換してみてください。
S2 フォーマットで出力されるようになるはずです。
cd binutils-2.8.1
gunzip -d srecfix.diff.gz | patch -p1
gmake
gmake install
kermit でモニタと通信
モニタとの通信はシリアルポートを通じて行います。
通信ソフトには私は kermit を使っています。
kermit を起動すると C-Kermit> とプロンプトが出るので、c (connect)
と入力するとリモートにつながります。
mkdir cku192
cd cku192
tar xvfz [somewhere]/cku192.tar.gz
set line [モニタとの通信ポート(/dev/cuaa0)]
set speed [モニタとの通信レート(19200)]
set terminal bytesize 8
set command bytesize 8
;
; don't wait prompt when transmit (default: wait 0x0a)
set transmit prompt 0
モニタにプログラムをロードする時はモニタで l コマンドを実行してから
Ctrl-\, Ctrl-C で kermit のプロンプトを再び出し、
と打ち込むとファイルが読み込まれます。読み込み終了後再び c (connect)とすると
モニタのプロンプトに戻ります。
transmit Sレコードファイル
gdb でリモートデバッグができるようにする
gdb を日立のモニタに対応させる
gdb では前述のシミュレータを使って、
ソースデバッグができます。
一方 H8の方には、日立のモニタが起動し、今回製作したクロスコンパイル環境で
コンパイルしたプログラムを RS-232C 経由でロードし、実行できるように
なっています。
今度はこれらモニタと gdb を直接接続して、開発プログラムを実際の H8 ボード
上でリモートデバッグできるようにします。
以上で改造は終りです。
このパッチ(gdb-hmon.tar.gz [2479bytes]) を
ダウンロードしてください。
cd [tmpdir]
tar xvfz gdb-hmon.tar.gz
cd [work]gdb-4.17/gdb
cp [tmpdir]/remote-hms.c .
patch -p < [tmpdir]/monitor.c.diff
gmake
gmake install
実機をリモートデバッグだ!
プログラムをコンパイルして gdb でリモートデバッグしてみます。
これをコンパイルします。
foo.c:
int func(int i);
int main()
{
int i, sum;
sum = 0;
for (i = 0; i < 10; i++){
sum += func(i);
}
}
int func(int i)
{
return i*i;
}
h8300-hms-gcc -mh -o foo.coff -g -Wl,-T[scriptfile] foo.c
テストプログラムが用意できたので、gdb でデバッグします。
% h8300-hms-gdb foo.coff
GNU gdb 4.17
Copyright 1998 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "--host=i386-unknown-freebsd2.2.6 --target=h8300-hms"...
(gdb) set machine h8300h <---- H8/300H を指定する
(gdb) set remotebaud 19200 <---- シリアルポートのボーレート
(gdb) target hms /dev/cuaa0 <---- モニタにコネクト
Remote target hms connected to /dev/cuaa0
0x0 in ?? ()
(gdb) load <---- プログラムをロード
.vectors : 0x00020000 .. 0x00020000
.text : 0x00020100 .. 0x00021054
.tors : 0x00021054 .. 0x00021054
.data : 0x00021054 .. 0x000212ec
.stack : 0x0003fffc .. 0x00040000 <-- section 毎のロード情報を表示
Transfer rate: 5248 bits/sec. <-- 転送レートを表示
(gdb) b main
Breakpoint 1 at 0x20134: file foo.c, line 6.
(gdb) b func
Breakpoint 2 at 0x2018c: file foo.c, line 15.
(gdb) run
Starting program: /home/work/h83/foo.coff
Breakpoint 1, main () at foo.c:6
6 sum = 0;
(gdb) n
8 for (i = 0; i < 10; i++){
(gdb) n
9 sum += func(i);
(gdb) n
Breakpoint 2, func (i=0) at foo.c:15
15 return i*i;
(gdb) p i
$1 = 0
(gdb) n
16 }
(gdb) n
main () at foo.c:8
8 for (i = 0; i < 10; i++){
(gdb) c
Continuing.
Breakpoint 2, func (i=1) at foo.c:15
15 return i*i;
(gdb) c
Continuing.
Breakpoint 2, func (i=2) at foo.c:15
15 return i*i;
(gdb) c
Continuing.
Breakpoint 2, func (i=3) at foo.c:15
15 return i*i;
(gdb) n
16 }
(gdb) n
main () at foo.c:8
8 for (i = 0; i < 10; i++){
(gdb) n
9 sum += func(i);
(gdb) p sum
$2 = 14
(gdb) q
これでリモートデバッグができるようになりました。
なお、gdb 起動時に毎回同じコマンドを打ち込むのが面倒なので、
gdb 起動時のカレントディレクトリに .gdbinit というファイルにコマンドを
あらかじめ記述しておくと良いでしょう。
.gdbinit:
set machine h8300h
set remotebaud 19200
RTOS を載せる
フリーの H8 用 uITRON準拠 RTOS HOS-H8 を GNU 開発環境用に移植しました。
こちらを御覧ください。
1 AS = h8300-hms-as 2 CC = h8300-hms-gcc 3 LD = h8300-hms-gcc 4 OBJCOPY = h8300-hms-objcopy 5 6 LOCALDIR = /usr/local/cross/hoso 7 INCDIR = ${LOCALDIR}/include 8 LIBDIR = ${LOCALDIR}/lib 9 LDSCRIPT = ${LIBDIR}/aki-h8.sh 10 #LDSCRIPT = ${LIBDIR}/sim.sh 11 LIBC = ${LIBDIR}/libc.a 12 VECTOR = ${LIBDIR}/vector.o 13 14 CFLAGS = -mh -g -O -I${INCDIR} 15 LDFLAGS = -mh -nostdlib -Wl,-T${LDSCRIPT} 16 MAP = -Wl,-Map,$*.map 17 18 PROG = hello.mot 19 OBJS = hello.o 20 21 .SUFFIXES: .mot .coff .o .c .s .h 22 23 .coff.mot: 24 ${OBJCOPY} -Osrec ${.IMPSRC} ${.TARGET} 25 26 all: ${PROG} 27 28 ${PROG}: ${OBJS} 29 ${LD} ${LDFLAGS} ${MAP} -o $*.coff ${LIBDIR}/crt0.o ${OBJS} ${LIBC} -lgcc ${VECTOR} 30 ${OBJCOPY} -Osrec $*.coff $*.mot 31 32 clean: 33 rm -f *.x *.coff *.mot *~ *.o *.map6行目〜8行目で、自作のライブラリや、インクルードファイル等のディレクトリ を定義し、ここに 自作 libc や AKI-H8 用のメモリ配置定義スクリプトファイ ルをインストールしています。
リンク時アドレス配置用スクリプトファイル (/usr/local/cross/h8300-hms/lib/ldscripts/h8300h.x) を見てください。
4 /* The memory size is 256KB to coincide with the simulator. 5 Don't change either without considering the other. */ 6 MEMORY 7 { 8 /* 0xc4 is a magic entry. We should have the linker just 9 skip over it one day... */ 10 vectors : o = 0x0000, l = 0xc4 11 magicvectors : o = 0xc4, l = 0x3c"0xc4 is a magic entry" というのは何のことを差しているのでしょうか? この答えは gdb のシミュレータソース (gdb-4.17/sim/h8300/compile.c) にあります。
442 /* And a jsr to 0xc4 is turned into a magic trap */ 443 444 if (dst->opcode == O (O_JSR, SB)) 445 { 446 if (dst->src.literal == 0xc4) 447 { 448 dst->opcode = O (O_SYSCALL, SB); 449 } 450 }opcode が JSR で literal が 0xc4 は "magic trap" だとあり、 opcode に SYSCALL を代入しています。SYSCALL 実行部分は次のようになっています。
1278 case O (O_SYSCALL, SB): 1279 { 1280 char c = cpu.regs[2]; 1281 sim_callback->write_stdout (sim_callback, &c, 1); 1282 }cpu.reg[2] を write_stdout() に渡しています。cpu.reg[2] は ER2 のことです。 つまり、 er2 の値を stdout に表示しているのです。
3 int _write(file, ptr, len) 4 int file; 5 char *ptr; 6 int len; 7 { 8 int todo; 9 10 for (todo = 0; todo < len; todo++) 11 { 12 asm("mov.b #0,r1l\n mov.b %0l,r2l\njsr @@0xc4" : : "r" (*ptr++) : "r1", "r2"); 13 } 14 return len; 15 }のコードが存在します。
これらのことから次の事が分かります。
ER2 に ASCII コードを設定して、jsr 0xc4 すると、シミュレータ内部では 0xc4 からのコードを処理することなく、設定された ASCII コードを stdout に 出力する。ということは、ベクタ 0xc4 にそのターゲット環境の1文字表示ルーチンを作る ことで、シミュレータとターゲットとで、同じ表示関数が使えることになります。
私は 0xc4 から LCD に1文字表示するプログラムを割り当ててあります。 LCD は 16x2行ですので、2行分32文字を1行分と定義し、改行が来ると次の表示 は先頭から表示し直すようにして、printf そのものを使えるようにしました。
その部分のメインコードを次に示します。
lcdout: ; r0l : カーソル push.l er0 push.l er3 cmp.b #'\n', r2l ; 改行ならカーソルをホームに bne l1 mov.b #0, r0l mov.b r0l, @_LcdCurPos bra l4 l1: mov.b @_LcdCurPos,r0l ; 表示するのが先頭ならクリア bne l2 mov.b #0b00000001, r0h PUTCMD r0h ; clear screen mov.l #0x1000,er3 ; wait 2ms w2a: sub.l #1,er3 bne w2a l2: cmp.b #32, r0l ; 32文字以上は表示できない bcc l4 mov r0l, r0h cmp.b #16, r0l ; 16文字以上は2行目に表示 bcs l3 add.b #(0x40-16), r0l l3: or.b #0x80, r0l PUTCMD r0l ; カーソル位置セット PUTDAT r2l ; 文字出力 inc.b r0h mov.b r0h, @_LcdCurPos l4: pop.l er3 pop.l er0 rts
asm("アセンブラ命令"); ex) #define DisableIRQ asm("orc.b #0xc0,ccr"); #define EnableIRQ asm("andc.b #0x3f,ccr")
typedef void (*fp)(void); const fp VectorTable[] __attribute__ ((section (".vectors"))) = { start, (fp)0L, (fp)0L, (fp)0L, /* 0x00- */ (fp)0L, (fp)0L, (fp)0L, (fp)0L, /* 0x10- */ (fp)0L, (fp)0L, (fp)0L, (fp)0L, /* 0x20- */ (fp)0L, (fp)0L, (fp)0L, (fp)0L, /* 0x30- */ (fp)0L, (fp)0L, (fp)0L, (fp)0L, /* 0x40- */ (fp)0L, (fp)0L, (fp)0L, (fp)0L, /* 0x50- */ itu0ent, (fp)0L, (fp)0L, (fp)0L, /* 0x60- */ (fp)0L, (fp)0L, (fp)0L, (fp)0L, /* 0x70- */ (fp)0L, (fp)0L, (fp)0L, (fp)0L, /* 0x80- */ (fp)0L, (fp)0L, (fp)0L, (fp)0L, /* 0x90- */ (fp)0L, (fp)0L, (fp)0L, (fp)0L, /* 0xa0- */ (fp)0L, (fp)0L, (fp)0L, (fp)0L, /* 0xb0- */ (fp)0L, putchar, (fp)0L, (fp)0L /* 0xc0- */ };
int count; #pragma interrupt void itu0ent(void) /* 周期タイマ割り込み */ { ITU0.TSR.BIT.IMFA = 0; /* 割り込み要因クリア */ count++; }
btst.b #7,@SSR0:8 ; 送信可能か? beq loop mov.b r0l,@TDR0 ; バッファが空で送信可能なら bclr.b #7,@SSR0:8 ; そのまま送信ここで :8 を付けるのを忘れないようにしましょう。
#define PADR (*(volatile unsigned char *)0xffffd3) int main() { PADR = 0x01; }これを
12a: 01 00 6d f6 mov.l er6,@-er7 12e: 0f f6 mov.l er7,er6 130: fa 01 mov.b #0x1,r2l 132: 6a aa 00 ff ff d3 mov.b r2l,@0xffffd3:32 ← !!!! ここ 138: 01 00 6d 76 mov.l @er7+,er6 13c: 54 70 rtsとなり、8ビットアドレッシングコードになっていないことがわかります。
-relax はバグっているのか?というと、そうではありません。ではどのような時
に期待している動作ができるかというと、「アドレス解決がリンカによって行わ
れる時」だけなのです。
つまり、リンカはアドレスを解決するようにアセンブラによって印が付けられた
インストラクション部分についてのみ、アドレッシングモードの最適化を行うの
です。
ですので、上記のようにアセンブラの時点までにアドレスが決まってしまった物
に付いてはリンカは処理を素通りさせてしまい、結果として期待通りの動作が
得られないということになっていたのです。
そこで、定数定義した物もリンカにもう一度アドレス解決してもらうように gas
を改造します。
このパッチ(gas-relax.diff.gz[319bytes])
を binutils-2.8.1/gas/config/tc-h8300.c にあてて、gas をコンパイルしなお
します。
このあと先程のプログラムをコンパイルしなおすと、
126: 01 00 6d f6 mov.l er6,@-er7 12a: 0f f6 mov.l er7,er6 12c: fa 01 mov.b #0x1,r2l 12e: 3a d3 mov.b r2l,@0xd3:8 ← !!!! 130: 01 00 6d 76 mov.l @er7+,er6 134: 54 70 rtsとなり、期待通りの結果になったことがわかります。
これで、目的は達成できるのですが、relax 処理にいくつかのバグがあるので、
このパッチ(ld-relax.diff.gz[425bytes])
も binutils-2.8.1/bfd/coff-h8300.c に当てておくと、より幸せになります
(このパッチはアドレス 0xff8000 の解決でエラーとなる問題と、bsr の 16 →
8の置き換えが signal 6 で core dump する問題に対処しています)。
int はデフォルト16ビットであることに注意
h8300-hms-gcc の int はデフォルト16ビット幅です。通常 gcc が対象とするアー
キテクチャではほとんどが int は32ビットとされています。このため、これを
仮定して作られているソースが newlib などに見受けられますので、オーバーフ
ローに注意が必要です。
私が引っかかったのは、mktime() です。libc/time/mktime.c のソースには、
/* compute hours, minutes, seconds */
tim += tim_p->tm_sec + (tim_p->tm_min * _SEC_IN_MINUTE) +
(tim_p->tm_hour * _SEC_IN_HOUR);
とありますが、右辺側の変数は全て int なので、16ビット幅での演算となり、
18時12分35秒を越えるとオーバーフローを起こします。
/* compute hours, minutes, seconds */
tim += tim_p->tm_sec + (tim_p->tm_min * _SEC_IN_MINUTE) +
((long)tim_p->tm_hour * _SEC_IN_HOUR);
======
とキャストします。
リンク
$Id: index.html,v 1.3 2003/06/29 16:03:23 hoso Exp $
(http://www.ops.dti.ne.jp/~coredump/)
私がクロスコンパイル環境を作るきっかけとなったページです。
SH用のgcc 開発環境、SH3 に BSD を移植する記事などがあり、
非常に楽しみです。
またリモートデバッガ移植の際にはいろいろとお世話になりました。
(http://member.nifty.ne.jp/Ryuz/)
H8用のフリーの uITRON 準拠 RTOS「HOS-H8」があります。
サイズコンパクトで、非常に気に入っています。
この GNU 移植版をこちら
で紹介しています。
(http://h8300-hms.sourceforge.net/)
H8クロス開発環境の最新版を得るのならここ。
Free PCB CAD soft の kban で有名な平田さんがメインで作業されています。
ここで紹介している幾つかのパッチが本家に取り込まれたのは平田さんの
おかげです。
[HOME]