H8/OS Ethernetドライバの改良内容についての記録です。


【オリジナルの処理方式】

EthernetコントローラICは受信した信号をリングバッファに蓄積します。ドライバではこのバッファを順に読み込みますが、オリジナルのH8/OSでは一旦、コントローラIC内のバッファにコピーを行い、ehter_read関数ではこのバッファからデータを読み出しています。
このような処理方式にしているのは、おそらく、IPパケットの処理中にARPパケットの処理を行うためではないかと予測します。具体的には下図に示すように、IPパケットを送信する際に、送信先のMACアドレスがARPテーブルに存在しない場合には、ARPパケットを送信しその応答を待ちます(図中の(6))。そのARPを受信するためには、受信したIPパケット(図中の(1))の読み取りを完了している必要があります。そのために一旦Ethernetコントローラ内の別のバッファreaddata(先頭アドレスがNE_DATA_PAGE*NE_PAGE_SIZE)にコピーを行っています。
ただし、この方法ではARPのリプライを受ける前に再送IPパケット等の別のIPパケットを受信するとreaddataに上書きがかかり、先に受信したパケットが破壊されてしまいます。

【Ringbuffer読み取りの修正】
最も適切な処理方法はパケットを受信したらRingbufferからH8CPUのメモリにすべてをコピーするか、Ringbufferの読み取り方法を高度化して到着した複数のパケットを並列して読み取れるようにすることですが、そのような処理方法に変更するのは非常に大掛かりな改造になってしまいます。そこで、次のような修正を行いました。
(a) 受信IPパケットの情報でARPテーブルを登録する
(b) Ringbufferを直接読み取る
まず、(a)は、IPパケットを受信した際には、そのリプライを送る先のMACアドレスを受信したEtherフレームから取得することにしました。すなわち、IPパケットを受信したら、そのパケットの送信元のIPパケットとMACアドレスをARPテーブルに登録するようにします。
これによって複数のパケットを受信する必要性はほとんどの場合はないので、上記図中のreaddataバッファも不要になるので、ne2000_read関数では、Ringbufferからデータを直接読み取るようにします。この変更が(b)です。
ただし、この変更により、IPパケットを受信した処理内で、そのIPパケットの送信元以外の端末へIPパケットを送信することはできなくなりますので、それを考慮したアプリケーションの作成が必要です。


戻る