(H8移植編第1回)H8への移植を考えよう

2009/08/31

あなたは 人目のお客様です.

ここのところOSC関西OSC名古屋に出展したが, やっぱし実機で動いているとインパクトあるので, ボードコンピュータへの移植を進めたいなあと思っていたのだが ちょっと時間がとれたので進めてみた.ようやく第一段階にたどりついた感じ.

まずはターゲットボードの選定なのだけど,いろいろ探したのだけど, 秋月電子H8/3069Fネット対応マイコンLANボード(完成品) というのに決めた.理由は以下.

ちなみに電源アダプタは別売りなので,5Vのやつを一緒に買う必要があります. これは秋葉原の秋月の店舗で買うなら,適当なのを一緒に買いましょう.

買ってから気がついたのだけど,付属のCD-ROMにフラッシュROM書き換えソフトが ついているのだけど,これがCのソースで配布されていて,FreeBSDでもあっさり コンパイルできて動作した.なのでWindowsに頼らずに,完全にFreeBSD上で 開発ができます(これはぼくにはとても嬉しい).

ちなみに秋月でもうひとつ,SH2の似たようなボードがあってそっちも候補だったの だけど,フラッシュROM書き換えソフトがWindows用なのでそれを使わないとならない. まあブートローダーだけ焼いてしまえばあとはOS開発では使うことはないのだけど, ちょっとイマイチではある.(実はそのSH2のボードも一緒に買ったのだけど, 最終的に上記の理由が決定打になってH8ボードをターゲットに決めた)

で,まずはクロスビルド環境の作成なのだけど,まあこれは付属のCD-ROMにtoolchainが 一式が入っているのだけど,当然ながらWindows用かLinux用になってしまう.やっぱし FreeBSD上で開発したいし,まあクロスコンパイラくらい自分で用意したいというのも あるので,いつもどおりbinutils+gccの組合せで,クロスビルド環境を構築する.

OSの起動には,ブートローダーをどこかから持ってきて動かして, OSはシリアル経由でダウンロードして動かす,という構成が開発には都合がいい. ブートローダーなのだけど,eCos付属のRedBootというのがH8に対応しているらしい.

ということで当初はRedBootを移植する予定だったのだけど,まあ結論から言っちゃうと RedBootは使わずに自前でブートローダーを作成することにしました.

なぜかというと,RedBootってC++で書いてある部分があるのでC++のクロスコンパイラが 必要になる.しかしgccのクロスコンパイラ作成時にc++有効にすると,ライブラリが なんか必要になってしまうようで,newlib入れたりとかいろいろ試したのだけどうまく クロスコンパイラが作れなかったのよ.c++を外すと簡単にコンパイラが作れるのだが.

で,たとえこれでなんとかc++のクロスコンパイラを用意したところで, この文書を読んで試すひとが同じようにはまったりしてもつまらないし, なんかクロスコンパイラ作成にひと苦労ってものなんだかな〜って気がするし, 組み込みOS作るならブートローダーくらい自作しても面白いんじゃないかと思う (OSの動作だけでなく,ブートストラップの勉強にもなる)ので,自作してみる ことにしました.ちょうどCQ出版から ブートローダーの本が出たことだし.(CQは,相変わらず良い本を出すね!みんな買いましょう!)

で,話がそれたけど,まずはクロスビルド環境の構築なのだけど,H8用のクロスの binutilsとgccは以下で構築できた.ちなみに環境はFreeBSD-6.2ね.

■ binutils-2.19 をインストール

% ./configure --target=h8300-elf --prefix=/usr/local --disable-nls
% gmake

# gmake install

■ gcc-3.4.6 をインストール

% cd gcc-3.4.6
% setenv SHELL /usr/local/bin/bash  (シェルがbash以外の場合)
% ./configure --target=h8300-elf --prefix=/usr/local --disable-nls --disable-threads --disable-shared --enable-languages=c
% gmake

# setenv SHELL /usr/local/bin/bash
# gmake install
あとフラッシュROM書き換え用のアプリなのだけど,h8write というのがCD-ROMに 付属しているのだけど,これはネット上の Open SH/H8 writer で配布されていて,しかもFreeBSDでも動くらしい. なのでいちおうネットのほうから最新版を持ってきて,以下の修正をしてビルドした.
% gcc h8write.c -o h8write
これであっさりビルド完了.
--- h8write.c~	Mon Aug 24 13:45:33 2009
+++ h8write.c	Mon Aug 24 13:45:52 2009
@@ -1,6 +1,6 @@
-#define		LINUX
+#undef		LINUX
 #undef		Solaris
-#undef		FreeBSD
+#define		FreeBSD
 #undef		Win32
 /*******************************************/
 /* EEPROM write program to H8/300H         */
@@ -42,7 +42,7 @@
  #define	RSLINE	"/dev/ttyS0"
 #endif
 #ifdef FreeBSD
- #define	RSLINE	"/dev/cuaa0"
+ #define	RSLINE	"/dev/cuad0"
 #endif
 #ifdef Solaris
  #define	RSLINE	"/dev/cua/b"
#define でプラットホームを指定しているけど,結局はシリアルデバイスをOSごとに 指定しているだけだったりする.ちなみにFreeBSDではFreeBSD-4.x系は /dev/cuaaX だけど,FreeBSD-6.x 系は /dev/cuadX になるので注意. (でも実行時にデバイス指定できるみたいなので,そうして使うならこの修正も いらないかも)

これで,ビルド環境はそろった. あとは以下あたりを参考にして,てきとうにサンプルプログラムを書いて フラッシュに焼いて動作させてみる.

上の「H8マイコンLANボードではじめる...」のほうに hello world のサンプル (h8_sci_rom.lzh)があるので, make.sh とか作ってとりあえずそれを動かしてみたら あっさり動いた. ただし上記サンプルでは,スタートアップでスタックポインタの設定がされていない ので,ちょっと不気味ではある.(設定忘れだと思う)

ちなみにフラッシュへの焼き込みだけど,以下のようにする.

  1. プログラムのビルドに成功するとELF形式の実行形式が作成される.これを objcopy を使ってモトローラSフォーマットに変換する.以下のような感じ.
    objcopy -O srec sample.elf sample.mot
    
  2. シリアルのストレートケーブル(シリアル延長ケーブル)でPCとボードを接続する.(クロスケーブルは不要)
  3. ディップスイッチを左からON,ON,OFF,ONにして起動.
  4. 作成した redboot.mot を h8write で焼く.
    h8write.exe -3069 -f20 redboot.mot
    
  5. 書き込み時に
    WARNING:This Line dosen't start with"S".
    Address Size seems wrong
    
    とかいうワーニングが出てたけど successed と言われたので,とりあえず気にしない.
  6. 以下のようにしてcuとかで38400bpsで接続する.
    # cu -s 38400 -l /dev/cuad0
    
  7. ディップスイッチを左からON,OFF,ON,OFFにしてリセットすることで, プログラムが起動する.リセットボタンを押すたびに hello world が表示される.
注意として,cuが起動しっぱなしで繋がったままだと,h8write で新たに書き込もうと しても書き込みできないので注意.h8write で書き込む際にはcuを切ること (シリアルがcuに占有されるので当然なのだが,ぼくはこれでけっこうハマった...). ちなみにcuは「~」「.」を押すことで切れます.

ちなみにCD-ROMにH8/OSというOSが付属していて,プログラムをメモリ上にロードして 実行する機能がある.さらにputというコマンドがCD-ROMに付属していて,FreeBSDにも 対応しているみたい.(h8writeと同様に,先頭にFreeBSD用の#defineがある)

ということでH8/OSをフラッシュに焼けばブートローダーとして使えて, putでKOZOSを送って実行する,ということができそう. まあでもネタとして面白いので,ブートローダー自作しようかとは思ってはいる.

で,まあとりあえず hello world くらいは全部自分で書いてみたいのと, 上記サンプルプログラムはグローバル変数の書き込みができないはずなので, hello world を自分でスクラッチで書いてみた.以下のような感じ.

以下の考慮をしてある.

まあこんなところかな.

ビルドの方法は簡単で,make.sh というスクリプトを用意してあるので, 以下のようにするだけです.PowerPCのと同じ感じ.

% ./make.sh clean
% ./make.sh
% ./make.sh image
./make.sh image することで,sample.mot が作成されます. で,スーパーユーザになって
# ./make.sh write
で,h8write を起動してフラッシュに書き込みます.シリアルは9600bpsで接続.

ちなみに以下が実行結果.グローバル変数の書き換えもばっちしうまくできてる みたい.

teapot# cu -l /dev/cuad0
Connected
Hello World! 10 1234 0 1 1 10
Hello World! 10 1234 0 1 1 10
Hello World! 10 1234 0 1 1 10

メールは kozos(アットマーク)kozos.jp まで