(注意)このブログは本家のほうの文章部分のみの転載です.ソースコードの配布,画像などについては本家のほうを参照してください.文章中のリンク先は面倒なのですべて本家のほうに変換してしまっているのでご注意ください.

H8への移植がひと段落したけれど,実はH8のボードを買ったときについでにSH2のボードも買っていて,なんとなくSH2のマニュアルを見ていたのだけど,なんか割り込み周りとかSCIのレジスタとか,H8とほとんど同じなので,実はKOZOS/H8をベースにしてSH2にもサクッと移植できてしまうのでは...と思ってSH2への移植をやってみた.

ターゲットボードは秋月電子の「AKI-7125マイコンボード」というもの.やはり完成品で,シリアルコネクタも実装済みなので半田づけは一切不要で買ってきたその日からすぐ遊べる.値段も4800円なので個人レベルで買える金額だ.シリアル経由でフラッシュROMを書き換えできるのもH8と同じ.ついでに,電源にH8/3069Fで使った電源アダプタがそのまま使えてさらに嬉しい.(SH/7144のボードは電源電圧が3.3Vなので,H8/3069Fボードと電源アダプタを共用できない)

画像はこちら

画像はこちら

このボードなのだけど,SH2の7125というCPUが載っている.SH2の中でも「SH/Tiny」とか呼ばれているやつで,SH2の中では比較的新しい,廉価版のSH2のようだ.

で,SH2への移植なのだけど,まず開発環境から.クロスコンパイラはH8のときとほとんど同じで,以下で作成できた.環境はいつもどおりFreeBSDね.

(binutils)

% ./configure --target=sh-elf --prefix=/usr/local --disable-nls
% gmake
# gmake install

(gcc)

% setenv SHELL /usr/local/bin/bash
% ./configure --target=sh-elf --prefix=/usr/local --disable-nls --disable-thread
s --disable-shared --enable-languages=c
% gmake
# setenv SHELL /usr/local/bin/bash
# gmake install

次にフラッシュROMの書き込みソフトなのだけど,ちょっといろいろ探してみたのだけどどうもFreeBSDから使えるもので,SH/7125に対応してるものが無い.実はSH/7144のボードも買ってあって,こっちだとfw(だったかな?)というシェアウエアがFreeBSD上で使えるみたいなのだけど,まあ最初だしよくわからんところではまってもしょうがないので,とりあえず添付CD-ROMに付属のWindows用の書き込みソフトを使うことにした.割と有名な「FDT」ってやつね.

移植はH8と同様に,ブートローダーとKOZOS本体の両方を移植する.理由はH8のときと同じ.ブートローダーはH8用に作ったものをそのまま移植.

ただしOSに関しては,SH/7125はRAMが8KBしかなくて,これはかなりきつい(H8/3069Fは16KB).OSが入りきるか心配だったのだけど,実際にH8用のソースコードを持ってきてSH2用にビルドして見ると,RAMのサイズが全然足りなくて入りきらない.ということでKOZOS/H8をベースにするのはあきらめて,Interface誌にPowerPC用に移植したときのかなりシェイプアップしたソースコードをベースにして移植を行った.

で,移植したソースコードは以下.

移植時に注意したこととかはまったことは以下.
  • RAMのサイズが足りないので,ELF形式でのダウンロードはやめてモトローラSフォーマットでの直接展開を利用する.
  • SHはアセンブラがちょっと特殊というか,癖があって慣れるまでちょっとひと苦労.意外なことに,アセンブラを書くための資料とか書籍が少なかった.(割り込み周りとか説明している書籍はあるが,メーカー純正コンパイラ(HEW)の#pragma 機能とか使ってアセンブラ書かずに実装している場合が多く,まったく参考にならないのが多い.がっくし)
  • SH2はジャンプ命令が遅延スロットを持つので,ジャンプ命令の後にNOPを入れておくとか考慮する必要有り.これは忘れがちなので要注意.
  • 50MHzと書いてあるのだけど起動時は実は25MHzで,50MHzで動作させるには分周比を設定しなおさないとならないみたい.SCIに供給するクロックはCPUとは別の分周比設定だが,これも25MHzになっているので,SCIのBCCの値を25MHzで計算する必要有り.
  • SCIが利用するCPUのピンが標準I/O入出力ポートとして割り当てられているので,SCIで使うという設定をする必要有り.これはブートローダーの serial_init() で行っている.(ブートローダーで設定しているので,OS側では現状でとくに設定はしていない)
  • SCIがデフォルトで省電力状態になっているので,起動後にシリアルの初期設定をしただけではシリアルが使えない(クロックが止まっている).STBCR3というレジスタを操作してクロック供給するようにする必要有り.(ブートローダーの serial_init() を参照.これはわりとハマッた.このへんのために,シリアル出力するだけでちょっとひと苦労)
  • RAMがとにかく少ないので,スレッドのスタックとかをさらに節約してギリギリまでメモリチューニングした.(スタック不足とかでたまに動かなくなったりしてハマることが数回あった)
  • シリアルの割り込みを有効にする際に,IPRLというレジスタを操作して,シリアル割り込みの優先度を設定しないといけない.これが起動時のデフォルトでは優先度最低になってしまっているため,割り込み有効化しても割り込みが入らない.これはかなりハマッたところだった...
  • ブートローダーの割り込みハンドラが

    void interrupt(int vec);

    のようになっていて,割り込み発生時にはintr.Sで割り込み番号を引数にしてinterrupt()を呼び出すのだけど,割り込み番号をアセンブラで設定する際に即値としてレジスタに設定するため,int型の値でなく1バイトの数値として符号拡張されてレジスタに値が入る.このためシリアル受信割り込み(221)がcharの上限を越えてしまい符号拡張されて,負の値になって interrupt() が呼ばれてしまうため,シリアル受信時に interrupt() がおかしなソフトウエア割り込みベクタを実行してしまい,誤動作していた.(割り込みが入ってもハンドラが呼ばれず,これはかなりハマッた)
  • 割り込みベクタ数がH8に比べて多く(H8は64個だが,SH2は256個),またRAMも少ないので,ソフトウエア・割り込みベクタを割り込みごとに用意するのはやめにしてひとつのハンドラですべてまかなうように変更(ハンドラ呼出し時に割り込みベクタ番号を引数にして関数コールするので,ハンドラでは番号見て処理を行う)
まあこんなところかな.最初のシリアル送信できるようになるまでと,OS起動後のSCI割り込み受け付けでハマッた.まあ赤と白のLEDがあったので,LEDデバッグでなんとかなりはしたのだけど,思いのほかハマッて苦戦した.やっぱし32ビットCPUは複雑さが全然違うね.H8よりずっと高機能で,動かすのにいろいろ設定も必要な感じ.

以下,実際に動かしてみたところ.動作方法はH8/3069Fとほとんど同じ.1点だけ,フラッシュROMの書き込みに h8write でなく FDT を使うので,このときだけはWindowsで作業する必要がある.

kzboot (kozos boot loader) started.
kzboot> load
~CLocal command? lsx kozos.mot
Sending kozos.mot, 94 blocks: Give your local XMODEM receive command now.
Bytes Sent: 12160 BPS:865

Transfer complete
eceive succeeded.
kzboot> run
starting from entry point: ffffa010
kozos boot succeed!

start command thread.
> echo test
test
OK
> threads
extintr
idle
command
OK
>

ブートローダーを起動してOSをダウンロードし,起動してコマンド受け付けできている.いやー,なんとか動いたね.よかったよかった.

雑感として,tinyといえどやはりSH2は32ビットRISCプロセッサだなあ,と思った.アセンブラとか,割り込み処理とか,レジスタ周りとか,I/Oポートまわりの設定の必要性とか,H8よりもはるかに複雑で,パッと見は似てるけど,路線というかポリシーはまったく違うCPUなのだなあ,と思った.対してH8は,やっぱしマイクロコントローラだなあ,という感じ.

そう思うとH8は移植が簡単だったなあ.シリアルとかタイマとか,たいして設定せずにあっさり動いたし.H8移植を先にやっといてよかったかも.

あとやっぱし8KBというのはOS動かすには少なくて,ROM上で動かすか,ライブラリ周りをROMに持っていってBIOSみたいにするか,なんか考えないとこれ以上の機能追加は現実,厳しい.H8/3069Fのボードは16KBある上におまけで2MBのDRAMがついている(マニュアルでは「あったらラッキーなおまけ」と書いてあるのだけど,web上のカタログでは必ずついているように書かれている.よくわからんけどまあだいたいついているもんだと思ってしまっていいみたいな気がする)ので,機能拡張していく楽しみがある.

H8はCISCなので最初はちょっとうーんと思っていたのだけど,逆にSH2はRISCなので32ビット即値をレジスタに直接代入することができず,値を近くのてきとうな場所に置いとく必要がある(このへんは,startup.s でのスタックポインタ設定とかmain()へのジャンプとかを参照してほしい).これがけっこう面倒で,32ビット即値を一撃で代入できるH8は楽で初心者にはいいなあ,と思う.初心者はH8ボードからはじめた方がいいかも.