【作業の流れ】(このページは編集中です)
ボードの作成
動作テスト
組込みソフトの開発
OSの改造 概要 改造の目的とソースの取得


【概要】
「組込みソフトの開発」で触れたようにキットに付属してくるH8OSのDRAM動作モードが実装されているDRAMに適合していないので、H8OSの設定を変えることにしました。また、プログラムが万一ハングアップしても自動的にリセットがかかるようにWDTをONに設定しました。
ソースはhttp://mes.sourceforge.jp/h8/index-j.htmlからV3.51をダウンロードし、これをエディットしています。コンパイルの方法は一緒に付属してくるindex.htmlに記載されていますが、make plus3068(モニタ込み)、make 3068(OSのみ)です。インクルードファイルのパス等は環境に合わせて変更する必要があります。
このサイトにも記載があるようにH8OSはGPL2ライセンスですので改造したソースはこちらのページで公開しています。


【改造点1(WDT)】
init.cで各種の初期設定が実施されています。最初に起動される関数はinit()ですので、その最初でWDTを有効にする次のコードを追加しました。

#define RSTCSR (*(volatile unsigned short *)0xffff8e)
RSTCSR = 0xa500 ;
TCSR = 0xa57E ;
TCNT = 0x5a00 ;

TCNT = 0x5a00はWDTのクリアですので、init()の各部に適宜このコードを挿入します。
また、モニタ(コマンド)には次の2カ所にこのコードを挿入しました。

  • コマンドループの先頭
  • dumpコマンドの処理

[追記 2009.9.26]
H8-3069Fボードを無線LANコンバータに接続したらWDTがタイムアウトしました。どうやらarpの処理に時間を要したようです。arp.cref_mac関数に作られたループ内にもTCNT = 0x5a00を挿入したら問題は解消しました。
[追記 2009.11.03]
無線LAN環境のような不安定なネットワークではNICの送受にも時間を要するようです。ne2000.cne2000_flush関数で送信状態を監視するループ2カ所についてもTCNT = 0x5a00を挿入しました。

【改造点2(DRAM)】
init.cのinit()から呼び出されるreg_init()では各種のレジスタを設定しています。 DRAMのモード設定もこの関数内で実施されていますので、 DRAMの利用で説明していますようにEDOモードをOFFにするようにDRCRAレジスタを0x35に設定するよう変更しました。

// DRCRA = 0x3c;
DRCRA = 0x35;


【改造点3(TCP再送対処)】
APLを開発している中でTCPを受信した際にデバッグのためにRS232Cにログを出力すると、複数回の同一内容のパケットをAPLが受信してしまいます。その結果、 シーケンス番号が正しく処理できず、TCPがハングアップしているようです。 H8OSのソースを確認したところ、どうやらTCPの再送を考慮していないようなので対処することにしました。
H8OSのプロトコルスタックで再送制御を行う方が望ましいのですが、大幅な改造になりそうなので、アプリケーションで対応することとしました。対処内容は次の通りです。

(1)シーケンス番号のAPLへの通知(メモリ領域拡大のためメモリ割り付けも変更。改造点5を参照)
(2)コネクション確立時のSYN+ACK信号紛失対応
(3)コネクション確立時のACK信号紛失対応
(4)ACK番号設定の改造
(5)コネクションクローズの改善

【改造点4(Ethernetドライバのリセット)】
アプリケーションのテストをしていると、なぜかpingさえ通らなくなる現象が発生します。アプリケーションに問題があるのかもしれませんが、このような状態になるとリセットボタンを押すしかありません。ドライバのne2000.cを見てみると、送信エラーやバッファのオバーフローのエラー処理が用意されていないところがありました。送信エラーについてはあまり発生することはないと思われるので、無限ループに入れて、WDTでリセットがかかるように修正しました。言うまでもないことですが、この対処はWDTを有効化しておくことが必須です。さもないとエラー時には無限ループに入り復旧しません。
また、バッファのオバーフローについてはRTL8019AS(EhternetコントローラのIC)をリセットするようにしました。

// ne2000.c
int ne2000_flush(int sendsize) {
:
:
/* 送信エラーのチェック */
if(NE_P0_TSR & NE_TSR_PTX) return 0;
// else return -1;
while(1) ;
return -1 ;

// ne2000.c
int ne2000_input(int memptr) {
:
:
// if(int_stat & NE_ISR_OVW) return -1;
if(int_stat & NE_ISR_OVW) {
  ne2000_init() ;
  return -1 ;
};

【改造点5(メモリマップ)】
OSを改造するとデフォルトのメモリ割付ではプログラムコードやデータの領域が不足したので、sys3068.x(カーネルのメモリ割付)やcom3068.x(モニタのメモリ割付)を修正しました。(執筆途中)

【改造点6(Ethernetリングバッファ)】
メモリ量を抑えるためか受信したデータをRTL8019AS(EhternetコントローラのIC)内の別のバッファにコピーしています。ただし複数のパケットを同時受信すると受信したバッファが不正な状態になるので修正しました。詳細は こちら

前<目次