秋月電子から発売されているH8マイコンボード・AKI-H8/3664Fは、値段が安い、コンパクト、周辺機能が豊富、そこそこの性能と、いいことづくめなのですが、RAM容量が2KBしかありません。アプリケーションをデバッグするにはこの2KBの領域にプログラムをダウンロードしなければならず、少し大きいプログラムをデバッグするにはいろいろと工夫が必要です。例えば、主要な部分をH8/3052などを積んだ規模の大きなマイコンボードでデバッグし、完成度が上がったらH8/3664Fに移植するなど、かなりまわりくどい方法を使う必要があります。
しかし、H8/3664は、
- ユーザープログラムからFlash-ROMに書き込み可能
- デバッグ用に、ブレークポイントレジスタが用意されている
という特徴があります。そこで、最初からFlash-ROMにプログラムをロードし、Flash-ROM上のプログラムをデバッグできるようなデバッガを作ることにしました。
問題は、Flash-ROMの書き換え回数です。メーカーが保証しているのは100回の書き換えまでです。ちょっと大きなプログラムをデバッグしようとすると、すぐに100回以上の書き換えが発生してしまいます。しかし、アマチュアが使うことを考えると、保証値ではなく、実力値で考えても良いでしょう。実際にどの程度の回数、書き換えが行われても大丈夫なものでしょうか・・・。1000回の書き換えが可能という説もあります。(私の持っている仕様書が古いのか、100回という記述しか見つけられなかった・・・)
実際のところ、100回を超える書き換えが発生してもすぐに使用できなくなるわけでは無いようです。デバッガ開発でも100回以上の書き換えを行いましたが、正常動作しています。じゃあ、アマチュアが使う分には問題なし、ということで、100回の書き換え制限は無視することにしました。
デバッガは、ベクタ領域を含む0x0000から0x0fffの4KBの領域に常駐します。ユーザープログラムをデバッグしたりデバッグ済みのプログラムを動かすのはこの0x1000から0x7f7fの28KB弱です。
ユーザープログラムのダウンロードには、H8/3664のユーザーモードFlash-ROM書き換え機能を使います。従って、プログラムのダウンロードの際にジャンパーピンを設定したり、リセットしてブートモードにする必要はありません。コマンドラインから"LO"コマンドを実行するだけです。
Flash-ROMの最終の128バイトは、ユーザープログラムの優先実行フラグです。0x7fff番地に0が書かれていると、即座にユーザープログラムを実行します。なので、デバッグ作業が終わったら、このフラグ領域に0を書くだけで、ROM化が完了することになります。
従来の開発スタイルでは、プログラムをRAM上にダウンロードするような設定でビルドし、デバッグが終わったらプログラムがROM上に配置されるようにビルドし直してからFlash-ROMに焼きこむ必要がありました。なので、ROM化の手順にミスがあったり、RAMとROMの特性の違いに起因するバグはROM化して初めて現象が発生するので、基本的にデバッガを使ったデバッグができず、試行錯誤を繰り返すことになります。
今回のデバッガでは、ユーザープログラムは最初からROMに配置されることと、デバッガが起動時、ユーザープログラムの優先実行フラグが立っているとそのままユーザープログラムを実行してくれるので、デバッガが存在しないのと同じに見えます。
もちろん、デバッガはROMに常駐しているので、ユーザープログラムを優先実行していて、レアな不具合が発生した場合は、NMIを発生させることで即座にデバッガに移ることも可能です。
そもそも、H8/3664にこの機能が装備されていたので、このデバッガを作ることにした、最重要の機能です。
普通、RAM上にプログラムをロードするタイプのデバッガは、ブレークポイントを実現する為に、停止させたいアドレスの命令を、TRAP命令などに書き換えます。目的のアドレスが実行されると、TRAP等によりソフトウェア割り込みが発生し、これをデバッガがキャッチしてデバッガの制御に移ることができるわけです。
しかし、ユーザープログラムをROMにロードするタイプのデバッガではこの手法が使えないため、なんらかのハードウェアサポートが必要になります。プロが使用するエミュレータやICEといった機器は、ROMをRAMでハードウェア的に置き換えたり、ハードウェアで常時アドレスバスを監視して、目的のアドレスにアクセスされた時に、強制的にCPUを停止するなどの機能でブレークポイントやステップ実行をサポートしています。
H8/3664には、このアドレスバス監視・割り込み発生回路が1つ装備されているので、Flash-ROMに書き込まれた状態のプログラムであっても、1ポイントのブレークポイントが実現可能なのです。
このデバッガは標準のデバッガと違い、ホスト側にかなりの部分を実装するような構成になっています。H8/3664の構成上、H8側に搭載するデバッガ本体のサイズを4KB以下に収めなければならないこと、デバッガとしては最低限ディスアッセンブラくらいは装備する必要があること、ソースレベルデバッグが無理なので、最低限、シンボルの表示機能程度は装備しないと実用にならないことなどから、機能の多くの部分をPC側に実装する以外に解決策が無かった為です。
しかし、この構成によって、デバッガの機能をマイコンボードのメモリサイズを気にする事無く実装することが出来ます。その気になれば、ソースレベルデバッガを作ることも可能でしょう。残念ながら、今回ターゲット用に使用する日立製の評価版Cコンパイラはデバッグ情報を吐き出さないようなので、生成されたABSファイルにはデバッグ情報が含まれておらず、ソースレベルデバッガの作成は不可能ですが。
H8/3664側のデバッガ本体は『adbg3664.abs』、ホストPC側のデバッガ(リモートデバッガ)は『adebug.exe』で、この2つが組み合わさって初めて機能します。以下、各ソフトウェアの構成です。
H8/3664側adbg3664.absの構成
- ROMは0x0000から0x0DFFまでの約3.5KBを占有。
- RAMは0xF780から0xF8BFまでの約320バイトを占有。ここには、各種割り込みハンドラを登録するための仮想割り込みベクタ、デバッガのワークエリア、通信バッファとスタックが含まれる。
- プログラムをダウンロードする時に、0xF8C0から0xFCFFの約1KB強を使用。ただし、ユーザープログラムをFlash-ROMに書き込む時だけ使用するので、ユーザープログラムのワークエリアとして使用可能。
- ホストPC側のリモートデバッガとの通信に、SCI3を使用する。但し、ユーザープログラム実行中はホストPC側のリモートデバッガは通常のターミナルプログラム動作に切り替わるため、ユーザープログラムからSCI3を使用可能。初期状態では、19200bps、8bit、STOP=1bit、パリティ無しの設定。
- リモートデバッガとの通信はバイナリ形式のパケット通信をする。BSC手順ライクな構成。0x02で始まって0x03で終了し、パケットのバイト数やチェックサムでパケットの判別を行う。
- adbg3664.absはNMIとRESETを占有するので、ユーザープログラムでNMIを使うことは出来ない。これ以外の割り込みはすべてユーザープログラムで使用可能。
- ビルドは秋月電子AKI-H8/3664F開発キット添付の、日立製H8S,H8/300 SERIES C Compiler Ver. 2.0D Evaluation software を使用。
- ユーザープログラムは0x1000番地から開始するものとして扱う。リンカのstartコマンドで実行開始番地が0x1000になるように調整する。
PC側リモートデバッガadebug.exeの構成
- コマンドプロンプトから起動するコンソールアプリ。
- Borland C++ 5.5とCygwin1-3-3でコンパイル出来ることを確認。
- 起動オプションでCOMポート、ボーレートを選択可能。デフォルトはCOM1、19200bps。
- ダウンロード可能なフォーマットは、日立製H8S,H8/300 SERIES C Compiler Ver. 2.0Dが生成するABSファイルフォーマット。
- ビルド時に生成されたMAPファイルから、グローバルシンボルを取得し、逆アセンブル時にシンボル情報を付加する。
- 各コマンドのパラメータは『計算式』が使用可能。
基本的な使用方法は、通常のソフトウェアをFlash-ROMに焼きこむ方法と変わりありません。Flash-ROMへのプログラムの焼きこみは、標準添付のコマンドライン版HTERM.EXEと3664.MOTを使用する方法と、ルネサステクノロジから無償提供されているFDT(Flash Development Toolkit)を用いる方法があります。書き込みの信頼性はFDTを使ったほうが良いように感じますが、あまり気にする必要は無いでしょう。以下は、FDTを使った例です。あらかじめ、適当なディレクトリに、adbg3664.mot、adebug.exeが展開されている状態を想定しています。さらに、テストプログラムを動作させてみる場合は(ここではtimerA.abs、timerA.MAP)それも展開しておきます。デバッガの焼き込みと動作確認だけであれば、H8用コンパイラが動く環境でなくともかまいません。
- AKI-H8/3664FマイコンボードのJP2、JP3をショートする。
- シリアルケーブルでPCと接続する。
- FDTを起動し、ウィザードに従って対象CPUの選択やCOMポートの選択をする。
- ターゲットボードの電源を入れ、念のため1回RESETスイッチを押す。
- FDTから、書き込み対象の『adbg3664.mot』を選び、STARTボタンを押す。
- 10秒程度でプログラムが終了する。
- ターゲットボードの電源を切り、ジャンパーを外す。
電源を投入すると、ADBG3664が動作します。標準添付のHTERM.EXEなどのターミナルプログラムを起動しておくと、以下のような起動メッセージが表示されます。これでデバッガが使用可能になります。
『ADBG3664 ROM Debugger for ...』の1行下に表示されているのが、デバッガからのバイナリパケットです。この状態で、ホストPC側のリモートデバッガ『adebug.exe』を動かすと、AKI-H8/3664ボードとパケット通信を始め、使用準備が完了します。
『adebug.exe』はデフォルトでCOM1を使用します。使用するポートがCOM1でない場合は、
adebug -c com3
のように、COMポートを指定して下さい。
AKI-H8/3664ボード側のデバッガバージョンを取得し、メモリ配置を表示すると、『>』(プロンプト)を表示してコマンド入力待ちになります。上の例では、Rコマンド(H8のレジスタを表示する)を実行した例です。HELPと打ち込むと、コマンドリストを表示します。
ここではサンプルとして、タイマーAとSCI3を使って約1秒毎にタイマーの値を表示するプログラム『timerA.c』をロード・実行する例を示します。
ロードするプログラムは timerA.ABS、デバッグで使用するシンボルは timerA.MAP です。これをadebug.exeを起動してロードすると、以下のようになります。
コマンドプロンプトから
adebug -m timera.map
とタイプすると、ターゲットボードとの通信、シンボル情報のロードを行います。この状態で、プログラムをFlash-ROMにロードするには以下のようにします。
LO timera.abs
でプログラムをFlash-ROMに書き込みます。自動的にユーザーエリアを消去し、ABSファイルからプログラムを抽出し、Flash-ROMに焼きます。およそ20秒ほどかかります。
正常にロードされたことを確認するために、_main 関数を逆アセンブルしてみます。
da _main
とタイプすると、グローバルシンボル _main から逆アセンブルします。サブルーチンの呼び出しや変数へのアクセスを行っている命令では、対象のシンボルを右に表示します。
R PC START
でプログラムカウンタをグローバルシンボル START(Cのランタイム初期化ルーチンの開始アドレス)に設定します。次に、
R SP 0xFF7C
で、スタックポインタをRAMの空き領域の最上位アドレスに設定します。
G コマンドで実行してみると、timerA.ABS の実行が開始され、main()関数の中でSCI3に出力している『longtmr=XXXXXXXX』の文字列が表示されています。
NMIスイッチを押すとデバッガに制御が戻り、『Abort by User』と表示され、レジスタと現在のPCの命令が逆アセンブル表示された後、コマンド入力待ちになります。
バイナリおよびソースを公開しますので、ご利用下さい。
ライセンスはBSDとします。
一応、お約束の免責事項です。このソフトウェアは無保証です。このソフトウェアを利用したことによって生じたいかなる損害に対しても、私は責任を負いません。
特に、このソフトウェアはFlash-ROMの書き換えを頻繁に行うことになります。RAM上でデバッグする通常のデバッガに比べ、確実にFlash-ROMの寿命は短くなります。
このデバッガは、ソフトを開発したあとは、そのままプログラムをユーザーモードで走らせ、作品に組み込んでしまうことを想定しています。そうでない使い方をする場合は、Flash-ROMの寿命に注意して下さい。
Version up 履歴
date version 内容 2008.04.21 adebug 0.3.49 式の評価で、最も小さい値のシンボルよりも小さな値でシンボルを検索するとExceptionが発生するバグを修正。 2008.04.21 adbg3664 0.4.57 STEP実行でまれに停止しないバグを修正。
注意:
実は、まだ十分にテストをしていません。バグレポートなどいただければ完成度Upの参考になります。よろしくお願いします。
このデバッガの動作確認を行った回路です。もともと、タカラトミーのiSobotというロボットをPCからコントロールするために作った回路です。要は学習リモコンなのですが、AKI-H8/3664Fの開発環境があまりにも小規模なので、しょうがなくてデバッガを作る羽目になったのです。AKI-H8/3664Fのマイコンボードと開発ソフトセットはずいぶん前(多分、2004年ころ)に購入したのですが、いままでほおって置いたのです。
注意を1点。下の回路図ではNMIに直接プッシュスイッチが繋がれていますが、チャタリングが発生してデバッガの中で再度NMIがかかる場合があります。そうなるとプログラムを継続して実行できなくなるので不便です。NMIで頻繁にABORTをかける場合は、NMIの入力にシュミットトリガとCRによる時定数を入れて波形整形したほうが良いでしょう。