H8-300Hのソフト開発をMacOSX上でやろう、の日記

←前へ
インデックス
次へ→


- テストプログラム


ごく簡単なテストプログラムをコンパイル、ダウンロードしてみよう。
AKI-LANは、3052のPORT-Aの下4bitにスイッチがついていて、PORT-Bの下4bitにLEDがついているので、まずはPORT-Aを読んでPORT-Bにコピーするだけのプログラムを動かしてみる。

File: test.c
#include "3052.h"

int main()
{
  PA.DDR = 0x00;
  PB.DDR = 0xff;
  while(1){
    PB.DR.BYTE = PA.DR.BYTE;
  }
  return 0;
}


この中で使っている3052.hは、秋月キットのCDROMに入っていた、H8/3048F用のヘッダ定義をほぼそのまま使ったもので、次の通り。
3052.h を見る

ただし、秋月の3052.hはint=16bitを想定しているものだったので、intを全てshortに変えた。

Makefileは次の通り。
Makefile を見る


% make

ローダが
warning: cannot find entry symbol _start; defaulting to 00000100
という警告メッセージを出したが、とりあえずは無視。(^_^;)
test.motが出来たので、これをh8writeで送り込む。
AKI-LANを書き込みモード(MD0-MD2をオープン、+12Vオン)にして、

% h8write test.mot

書き込みに成功。モード6に戻して、AKI-LANの電源を入れ直す。
PA3のスイッチを押すと、PB3のLEDが光る。
PA2のスイッチを押すと、PB2のLEDが光る。
...動作OK。


- GDB


デバッガGDBをインストールする。
ftp://ftp.ring.gr.jp/pub/GNU/
から、gdb-6.3.tar.gzをダウンロード。

% tar xzf gdb-6.3.tar.gz
% cd gdb-6.3
% mkdir objdir
% cd objdir
% ../configure --prefix=/Users/shibuya/work/h8 --target=h8300-hms
% make
...しかし、libintlで引っかかって、うまくコンパイルできなかった。

あらためて、gdb-6.2.tar.gzでトライ。
% tar xzf gdb-6.2.tar.gz
% cd gdb-6.2
% mkdir objdir
% cd objdir
% ../configure --prefix=/Users/shibuya/work/h8 --target=h8300-hms
% make
今度は成功。
% make install

これで、/Users/shibuya/work/h8/bin内に、h8300-hms-gdbなどが出来上がった。
これからよく使うことになりそうなので、aliasをbashに登録しておく。
% vi ~/bashrc
alias hgdb="${HOME}/work/h8/bin/h8300-hms-gdb"
を追加。

gdbのテスト。
先ほどのMakefileの"CFLAGS"の最後に"-g"を付け加えてコンパイルし直す。

% make clean;make
% hgdb test.out
(gdb) disassemble main
Dump of assembler code for function main:
0x00000100 <main+0>:    01 00 6d f6       mov.l er6,@-er7
0x00000104 <main+4>:    0f f6             mov.l er7,er6
0x00000106 <main+6>:    18 aa             sub.b r2l,r2l
0x00000108 <main+8>:    3a d1             mov.b r2l,@0xd1:8
0x0000010a <main+10>:   fa ff             mov.b #0xff,r2l
0x0000010c <main+12>:   3a d4             mov.b r2l,@0xd4:8
0x0000010e <main+14>:   2a d3             mov.b @0xd3:8,r2l
0x00000110 <main+16>:   3a d6             mov.b r2l,@0xd6:8
0x00000112 <main+18>:   40 fa             bra   .-6 (0x10e)
End of assembler dump.

どうやらちゃんと動いているようだ。(ターゲット接続はしていないが。)


- リンカスクリプトとスタートアップコード


さっきは、初期化も何もしないで適当にプログラムを動かしたが、これでは関数呼出しもできない(スタック未設定)し、グローバル変数も使えない(DATA/BSSセクション未設定)ので、ダメである。
ちゃんとしたリンカスクリプトとスタートアップコードを作ろう。

h8300-hms/lib/ldscripts/h8300h.xファイルを参考に、次のリンカスクリプトを作った。
h8300h.x を見る

要点は、
+ 通常のワーク領域(.dataおよび.bssセクション)をAKI-LANボードについている外付けSRAM(0x220000〜0x23ffffの128KB)に配置した。
+ スタックはH8/3052内蔵のRAM(0xffdf10〜0xffff0f)に配置した。
+ コード(.text)セクションの直後に、初期化変数の初期値を配置した。変数の実態は.dataセクション内。
+ .vectorセクションは割り込みベクタ用。
+ .tinyセクションは16bit絶対アドレッシング用。
+ .eightセクションは8bit絶対アドレッシング用。

また、このスクリプトに対応したスタートアップコードも作った。
crt0.S を見る

こちらの要点は、
+ リセット時にstart関数に飛ぶ。
+ start関数では、まずアドレスバス、データバス、CS0-3などが使えるように設定。
+ 次に、スタックを設定。
+ .dataセクションにROM内の初期値をコピー。
+ .bssセクションをゼロクリア。
+ main関数を呼ぶ。

さて、これをテストするサンプルプログラムを作る。
File: test2.c
#include "3052.h"

int testvar = 5;
int testvar2;

void testfunc()
{
  int i,j;
  for(i = 0; i < 5; i++){
    PB.DR.BYTE = ~i;
    for(j = 0; j < 200000; j++)
      ;
  }
  for(i = 0; i < testvar; i++){
    PB.DR.BYTE = ~i;
    for(j = 0; j < 400000; j++)
      ;
  }
  for(i = 0; i < testvar2; i++){
    PB.DR.BYTE = ~i;
    for(j = 0; j < 600000; j++)
      ;
  }
}

int main()
{
  int i;

  PA.DDR = 0x00;
  PB.DDR = 0xff;
  PB.DR.BYTE = 0xff;
  while(1){
    testfunc();
    PB.DR.BYTE = 0xff;
    for(i = 0; i < 1000000; i++)
      ;
  }
  return 0;
}


testvarは.dataセクションに割り当てられる。testvar2は.bssセクションに割り当てられる。
プログラムの動作は、まず0〜4をPORT-BのLEDで順に表示。もしtestvarの初期化がきちんとできていれば、もう一度0〜4をゆっくり表示。もしtestvar2の初期化が出来ていなければ、さらにゆっくりLEDが表示される。

これをコンパイルするMakefileは次の通り。
Makefile を見る


% make
% h8write test2.mot
で、動作確認。
LEDは0〜4を表示し、もう一度0〜4をゆっくり表示、消えた。(これを繰り返す。)
うまく動いているようだ。

(後日談)
この開発環境でいくつかのプログラムを作っていたら、ある時全く起動不能になるプログラムができてしまった。
不思議に思い調べてみたところ、グローバル変数の配置の都合で、BSSセクションがたまたま奇数バイトになっていたため、上のcrt0.Sではスタートアップルーチンが暴走するのであった。
そこで、リンカスクリプトを次のように変えて解決した。
h8300h.x を見る

変更点は、各セクションの終わりに、
. = ALIGN(2)
を加えて、セクションの長さが偶数になるようにした点である。


- モニタプログラム


H8/300H用の簡易モニタプログラムがフリーで公開されていたので、試してみる。

http://www.toppers.jp/contrib/h8mon-1.12.tar.gz
をダウンロード。

% tar xzf h8mon-1.12.tar.gz
% cd h8mon
% h8write mon3052/mon3052.mot

シリアルターミナルソフトはminicomを使おう。
% fink install minicom
% sudo minicom -s
しかし、うんともすんとも画面が変わらない。

すぐにあきらめて、自分でソースから作ってみる。
http://alioth.debian.org/projects/minicom/
から、バージョン2.1のソースをダウンロード。
% tar xzf minicom-2.1.tar.gz
% cd minicom-2.1
% ./configure
% make
% sudo make install

いちおう、
% fink remove minicom
をやっておく。

% sudo minicom -s
で、設定画面が出てきた。
しかし、設定保存ができなかったので、
% sudo mkdir /usr/local/etc
で保存ディレクトリを作成。
Ctrl-A oで設定画面を出し、シリアルポートを"/dev/cu.I-O DATA USB-RSAQ3"にして、ロックファイルディレクトリを"/usr/local/spool/lock"にした。また、Modem初期化コードを"^M"に、Modemリセットコードを""(なし)にした。
これをデフォルトとして保存。

一度minicomを終了して、
% sudo mkdir /usr/local/spool
% sudo mkdir /usr/local/spool/lock
% sudo chmod a+w /usr/local/spool/lock
としておく。
% minicom
しかし、"/dev/cu.I-O"にアクセスできない、というメッセージが。どうやら、デバイス名に空白が入っているとダメらしい。
そこで、
% ls -l /dev/cu.I-O*
crw-rw-rw-  1 root  wheel    8,  13 25 Feb 22:03 /dev/cu.I-O DATA USB-RSAQ3
とやって、デバイスノードのメジャー番号8とマイナー番号13を確認。
% sudo mknod /dev/cu.USB-COM c 8 13
% sudo chmod a+rw /dev/cu.USB-COM
とやって、デバイスを作ってしまう。(ちから技。^_^;;)
これで、minicomが動くようになった。
minicomを起動してから、AKI-LANの電源を入れると、

8/3052F Monitor v1.12 Copyright (C) 1999-2004 CSE Tomakomai NCT
1:                                                   

と表示された。
h8mon付属のreadme.txtを読んで、動作を確認。OK。


- モニタ対応テストプログラム


さきほどのtest2をh8mon対応にコンパイルし直してみよう。
ソースコードは全く変える必要がなく、リンカスクリプトだけを次のように変える。

h8300h_mon.x を見る

変更点は、.vectorsセクションを0xffe000にした所と、romを無くして.textセクションもramに配置した所。

Makefileの"h8300h.x"の所を"h8300h_mon.x"に変えてコンパイルし直す。

% make clean;make

minicomを起動して、

% minicom
H8/3052F Monitor v1.12 Copyright (C) 1999-2004 CSE Tomakomai NCT
1:ld
(Ctrl+A sでファイル送信メニューを開き、asciiプロトコルでtest2.motを送信)

が、しかし、反応無し。。。
minicomの設定を確認したら、File transfer protocolsのasciiが、"/usr/bin/ascii-xfr"になっていた。これではダメなので、"/usr/local/bin/ascii-xfr"に変えて再度チャレンジ。

が、しかし、反応無し。。。
いろいろ試してみた所、どうやら、ファイル内容を一気に送信するとAKI-LANの反応が無くなる。h8monのソースコードをいじって9600bpsにしてもダメだった。

「H8-300Hのソフト開発をMacOSX上でやろう」という趣旨には若干反するが、試しにLinux機で同じことをやってみた。
結果は、一発OK。38400bpsでも9600bpsでも、問題なくtest2.monのダウンロードができ、goコマンドでちゃんと動作した。

どうやら、minicomの挙動がおかしい。もしかすると、IO DATAのシリアルドライバ(またはUSB-シリアル変換ハード)がおかしいのかもしれないが。

というわけで、急遽、ダウンロードプログラムを作ってみた。

h8load.c を見る

Makefile を見る


% make
% sudo cp h8load /usr/local/bin
とやって、いつでも使えるようにしておく。

あらためて、

% h8load test2.mot
で、無事動作した。(h8loadは、"ld"コマンドの発行と"go"コマンドの発行も行なっているので、これだけでダウンロードして実行する。)

ところで、このモニタ下でプログラムを実行すると、LEDの点滅の速度がROMの時に比べてだいぶ遅くなった。
これは、H8/3052の内部ROMへのアクセスが2サイクルで行なわれるのに対し、外部RAMへのアクセスが3サイクルで、しかも8bitアクセスをしていることによる。
(正確には、AKI-LANボードについている外付けRAM回路がそうなっているという話である。念のため。)


←前へ
インデックス
次へ→
Last updated: 2005/4/24 14:14
Copyright (C) 2005 by SHIBUYA K.
All Rights Reserved.