AKI-H8-USB+GCCで始める H8入門
ちょっとだけ大きなマイコン開発のことはじめ

はじめに

今回はPICやAVRからちょっと背伸びをして秋月電子通商のAKI-H8-USBでH8を使ったUSB開発を始めます。秋月電子通商のAKI-H8-USBは、USBコントローラを搭載したCPUボードです。CPUは日立のH8/300Hシリーズで、H8/3048版とH8/3052版の2種類あります。USBコントローラはNationalSemiconductorのUSBN9604で、バイトアクセスのCPU I/Fを持つコントローラです。
開発環境は作業の仕易さからWindowsXPで済ませたいので、クロス開発環境としてcygwin+GCCを使ってアセンブラとC言語で開発します。

マイコン開発でC言語を使ったのはコレがはじめて…。

↓今回購入したAKI-H8-USB (H8/3048) 8000円也

これに、16×2キャラクタLCDモジュールを使ってみよう。で使ったキャラクタLCDモジュールが付いています。


AKI-H8-USBの製作

ボードを組み立てる

キット付属の資料とCD-Rに入っているHTML資料を舐めるように読み、キットを組み立てます。部品表と基盤をよく確認し、丁寧にハンダ付けしていけば簡単に組みあがります・・と言いたい所ですが、40ピンのソケットをいっぺんにハンダ付けしようとすると、ソケットがまっすぐに入らなくて意外に苦労しました。丁寧にやればいらない苦労はしなくてすんだのに・・・。
組みあがったら、サンプルソフトを付属CD-ROMからコピーして、付属のZ-FTATのFLASHメモリの書き込みソフトをPCにインストールします。
H8マイコンボードのCPUモードは、今回は使い分けるのも面倒なのでモード6を使います。CN5の1-2をジャンパでつなげばOKです。


開発環境のテスト、とりあえずLED

続いて付属アセンブラをテストします、何を始めるにしても、コレができないと始まりません。
AKI-H8-USBにはクロス開発環境として付属アセンブラがあります。まずはコレを使ってLEDを点灯させて見ましょう。

秋月付属アセンブラ用プログラムサンプル
LED点灯プログラム:
led_test.asm
モトローラSファイル:
led_test.mot

プログラムを秋月の付属アセンブラと同じディレクトリに入れて、以下の通りに実行します。
アセンブルする:
> A38H led_test.asm  
 led_test.lstとled_test.objができます。

オブジェクトファイルをリンクする。:
> L38H led_test.obj
 led_test.absができます。

Sフォーマットへコンバートする:
> C38H led_test.abs
 これでSフォーマットのled_test.motができてコンパイル終了です。

 コレを付属のZ-FTATのFLASHメモリの書き込みソフトでライトすればOKです。
ライタはこの付属ライタを用います。

AKI-H8-USBのD-SUB9ピンメスの端子CN501D-SUB9ピン オスのケーブルでPCのCOM端子に接続します。
このケーブルは秋月で単体販売されています。

↓付属のライタソフトを起動すると、まず、このウィンドウが開きます。

ここでOKを押して、AKI-H8-USBのスライドスイッチSW500、501、502のスイッチをON(+12がハッキリ光る)にし、 電源をONにして、リセットボタンを押すと次のウィンドウが開きます。

↓交信中、しばし待つ

次は、書き込むファイルと書き込むアドレスの指定です。メニューバーのwriteでled_test.motを指定して、書き込みます。

↓書き込みウィンドウ

書き込み終了後は、スライドスイッチSW500、501、502のスイッチをOFF(光が暗くなる)にしてリセットを押せば動作が開始します。

↓おなじみLED点灯プログラム

うん、動作しました。コレで安心。
はじめての環境では、まずコレをやらないと落ち着きませんねぇ。


AKI-H8-USBをジョイスティックにする

次にUSB周りの回路の動作をチェックします。
とりあえず、ジョイスティックのサンプルを書き込んでUSBに接続します。
HTML資料を舐めるように読みなおして、キャラクタLCDモジュールを接続します。

↓USBを接続したところ。

接続するとUSBジョイスティックとして認識します。
当たり前のようにHIDデバイスとして認識しています。タクトスイッチを押してみましょう。

↓動作確認

コレが確認できればUSB関連の結線も大丈夫でしょう。
後は他のピンがハンダ不良になっていないことを祈るのみです。 ボードの確認が取れたところで、ソフト開発環境の構築を始めます。


C言語開発環境のセットアップ

付属アセンブラはこれで十分使えるものなのですが、今回はおべんきょも兼ねて開発環境をGCCにします。これからも良く使うと思うので、環境設定を覚えるには良い機会です。
今回は、LinuxなどのフリーUNIXマシンを別に用意するのは面倒なのでcygwin上でH8クロス開発環境を構築します。

cygwin環境のセットアップは以下の手順で行います。
1、cygwinのインストール
2、Windowsの環境変数設定
3、cygwinの環境設定

↓RedHatのcygwinのサイト
http://sources.redhat.com/cygwin/

H8開発用のGCC環境のセットアップは以下の3つのインストールする必要があります。
binutils  バイナリ関係
gcc      GCC本体
newlib   簡易ライブラリ ←コレのインストールが長いです。

これらのソースとコンパイル方法はStrawberry Linuxのサイトを参考にしました。
↓Strawberry Linuxのサイト
http://strawberry-linux.com/
・・・のですが、コンパイルがなかなかうまくいかず、cygwin版H8開発環境のバイナリがあったので、それを使わせてもらいました。

↓村中さんのサイト
http://www.ertl.ics.tut.ac.jp/~muranaka/devel/
面倒で時間のかかるコンパイルの手間が省けて便利です。
他にもSH版のバイナリやコンパイルメモがあり大変参考になりました。
コレで開発環境は整いました。

C言語版LED点灯プログラムを作る

OS上で動作させるアプリケーションの開発環境は、OSのロード機能を使ってメモリにプログラムを展開していますが、今回のように何もない場合は、ハードの初期化処理をアセンブラで記述したスタートアップルーチンと、メモリの配置情報を記述したリンカスクリプトが必要です。C言語の仕様では割り込みベクタとか、スタックの確保とか、プログラムの配置等は記述できませんので、当然、アセンブラだったり、コンパイラ特有のスクリプトだったりします。

サンプル
LED点灯プログラムのCソース:
led_test_gcc.lzh

中身は以下の通りです。
h8_3048f.x   H8/3048用のリンカスクリプト
h8_3048f.S  スタートアップルーチン
led_test.c    Cソース
Build.bat     コンパイルコマンドを記述したバッチファイル

コンパイル方法は以下の通りです。
リンカスクリプトとスタートアップルーチンを指定してコンパイル。
> h8300-hms-coff-gcc -mh -mint32 -T h8_3048f.x -nostartfiles h8_3048f.S led_test.c -o led_test.coff
オブジェクトファイルをSフォーマットへ変換。
> h8300-hms-coff-objcopy -O srec led_test.coff led_test.mot

Build.batに記述してあります。

リンカスクリプトとスタートアップルーチン

リンカスクリプトとはメモリーマップ上にデータは何処に置けるかプログラムは何処に置けるか等を定義したロケート情報が入っているld(リンカ)のスクリプトです。オブジェクトにアドレスを振る(リンクする)際に必要となります。メモリマップはターゲットのCPUのプログラムメモリワークメモリ外部メモリアドレスサイズによって変化するので、リンカスクリプトはターゲットのハード構成ごとに、作成する必要があります。
GCCではロケート情報をリンカスクリプトにすることでリンカがアドレスを解決します。GCCのリンカスクリプトの詳細な内容は以下の資料を参考にしてください。

↓Redhatの 組込みトップ > 組込み・ダウンロードのリンカスクリプト
http://www.jp.redhat.com/download/cygnus/doc/linker-scripts.pdf


スタートアップルーチンはCPUがプログラムを動かす上で最初に必要な動作が記述されているアセンブラソースです。具体的には、スタックポインタの初期化とかROMのデータをRAMに再配置とかmain関数の呼び出し等です。Cのプログラムはmain関数から始まりますが、プログラムはプログラムカウンタのリセット値(0である場合が多い)から始まるわけですから、プログラムカウンタの値をmain関数の位置にとばすプログラムも必要になります。main関数はさらに引数があるので、スタックが必要になります。だからmain関数を呼ぶ前にスタックポインタを初期化する必要があるわけです。


実はこの2つのどちらを使っても割り込みベクタを記述することが可能です。どちらに書くかはプログラマ次第です。gccコマンドはオプション-vを追加してコンパイルするとコンパイルの各動作が表示されるので、コレを見ながら正しくコンパイルされているか確認します。


Cソース版を実行する

今回のソースは説明するも恥ずかしいforループのLED点灯ルーチンです。手抜き〜。LEDはポートBに繋がっているのでデータディレクションレジスタの[0:3]を出力方向にして、データレジスタのHi、Lowを適当に変化させているだけです。
というわけで、早速書き込み。

↓見るまでもないけど


あー、アセンブラ版の実験写真と同じに見えるのは気のせいです・・・とごまかしておきます。
Cによる開発環境の確認できたので、この環境で開発できます。


機能追加

SRAMを増設

AKI-H8-USBには付属に1MbitのSRAMがあります。次は1Mbit SRAMを搭載して動作を確認します。
せっかくなので、メモリの動作を直接観察します。あーロジアナ、ロジアナ・・・。

↓追加したSRAM 東芝TC551001C


サンプル
SRAMを使用したLED点灯プログラム:
sram_test_gcc.lzh

中身は以下の通りです。
h8_3048f.x   H8/3048用のリンカスクリプト
h8_3048f.S  スタートアップルーチン
sram_test.c    Cソース
Build.bat     コンパイルコマンドを記述したバッチファイル

外部メモリをワークメモリに当てられるようにリンカスクリプトに変更を加えていますが、プログラム上は意味がありませんのであしからず。
コンパイル方法もLEDと変わりません、Build.batにまとめてあります。

これは基本的に↑で実験したLED点灯プログラムと同じですが、一旦SRAMにデータを書き込んでからポートBのデータレジスタにロードしています。
アドレスの17ビット目がチップセレクトになっているので、そこは常にONにするためSRAMのアドレスが220000〜23ffffとなります。バイトアクセスなのでメモリ容量は8×131072=1Mbitまで搭載可能です。
H8にプログラムを書き込んで、実際にメモリに書き込んでいるところをロジアナでプローブしてみました。

↓ロジアナでプローブ。

久々登場、ロジアナ98です。カメレオンUSBは不調でお休み。

↓上の4つがチップセレクトと各イネーブルです。データはプローブしてません。

Write、Writeした後、Readしています。
9番から下は思い違いで上手くWriteしていなくて苦労していたときの波形です。
こうやって残すとReadしたときに全然データが出なくて苦悩していたころを思い出します・・・
まぁ、気付いたから良いけど。

↓動作風景

あー、もう見飽きたとは言わないで・・・。

これでSRAMの動作が確認できました。
Cでプログラムできるようになったし、ちょっと複雑なプログラムにチャレンジしたくなります。
とりあえず、SRAMをフレームバッファにしてUSB接続のLCDコントローラにでもしてみようかなぁ。

やり残したこと

GASが使えない・・・。

GCCセットアップするにあたり、秋月付属のアセンブラでしたことを試そうと実験してみました。
サンプル:
led_test.s GAS版LED点灯プログラム。
ところが、h8300-hms-coff-asでアセンブルしたところ、ジャンプ命令とブランチ命令のアドレスが解決されず動作しません。
2週間ほどイロイロ試して見ましたが、結局今回はあきらめて先に進むことにしました。
うーん、後で必ずリベンジします。根性があれば。


今回学んだこと

リンカじゃなくてロケータだろ。
・・・まぁコマンドがldだから仕方ないか。
GCCコンパイルは長い、newlibはもっと長い。
忙しい時はバイナリパッケージに逃げるのも手。
あーどこがCなの?
はい、ほとんどアセンブラです、以前、アセンブラ知らずにCをやるのは不可解だという人がいました。まったくその通りだったとは・・・。
SRAMのCSは2つあります。CS1がLowアクティブ、CS2がHiアクティブです。両方がアサートされて始めて動作します。
CSがひとつと思い込んでいた私が馬鹿でした。
無理してこだわる必要はない。
思い切って後回しにする。無駄ではないけど、時間を使いすぎるのも問題。