(H8移植編その2第5回)IP通信をごっそり書き直した

2010/10/10

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

しばらくシミュレータ対応を進めていたのだけど,シミュレータでネットワーク通信が できるようになったので,そろそろTCP/IPの実装に戻ろうかと思う.

で,前回のH8移植編その2第4回についてなのだが, ARPとpingに応答するだけのはっきり言ってかなりやっつけのコードになっていて, これをこのまま発展させてTCP/IPを実装するのはキツイ.まあプロトタイプは プロトタイプと割り切って捨ててしまって,ちゃんと設計し直してごっそり書き直した ほうがいい.ていうか,前回のコードを発展させてTCP/IP実装しようとやってみたら 全然うまく書けなくて,もういっそネットワークまわりを最初から書き直して しまおうとやってみたらうまく書けた.

で,今回紹介するコードなのだけど, 前回のH8移植編その2第4回ではなく, 「(シミュレータ編第6回)ネットワーク対応だ!」 のソースコードをベースにしてごっそり改造した.

というのは,もともと 「(H8移植編その2第4回)ネットワークに接続しよう」 のコードをシミュレータ対応して 「(シミュレータ編第6回)ネットワーク対応だ!」 のコードを書いている.なのでこっちをベースにすれば,シミュレータ対応された 状態で開発が進められるからだ.

ただネットワークまわりはごっそり書き直してあるので,ほぼ原型をとどめていない. 以下のように書き直してある.

以下,修正したソース.

(2013/01/12追記:注意)
@IT MONOistの 「H8マイコンボードで動作する組み込みOSを自作してみよう!(6) :「ping」によるネットワーク通信機能を実装してみよう」 の記事を参照して以下を試すかたは,以下ソースコードに ページ末尾の修正を入れてください. でないと受信が正常に動作しません.

GDBにもパッチを当てる必要がある.これは 「(シミュレータ編第6回)ネットワーク対応だ!」 まででGDBに対して加えている修正に加えて,さらに上記ソースコードの gdbというフォルダにある device.c に対するパッチを当てること.

で,OSのソースコードについてだが, 修正点多すぎてここではいちいち説明しないけど,以下の動作ができます.

いちおうマイコンボード→PC方向と,その逆方向の両方でping開始して 応答することを確認した.以下,実行時のログ.

(KOZOS→PCへのping発行)

command> ICMP received: c0a80a01 00 00 08eb
ICMP received: c0a80a01 00 00 08ea
ICMP received: c0a80a01 00 00 08e9

unknown.
command> 

(PC→KOZOSへのping発行)

hiroaki@teapot:~>% ping 192.168.10.16
PING 192.168.10.16 (192.168.10.16): 56 data bytes
64 bytes from 192.168.10.16: icmp_seq=0 ttl=64 time=299.465 ms
64 bytes from 192.168.10.16: icmp_seq=1 ttl=64 time=296.996 ms
64 bytes from 192.168.10.16: icmp_seq=2 ttl=64 time=297.040 ms
64 bytes from 192.168.10.16: icmp_seq=3 ttl=64 time=297.128 ms
64 bytes from 192.168.10.16: icmp_seq=4 ttl=64 time=297.412 ms
^C
--- 192.168.10.16 ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/stddev = 296.996/297.608/299.465/0.940 ms
hiroaki@teapot:~>% 

ちなみに今回はネットワークまわりをほとんど全部書き換えて,タスク間通信で やりとりするように設計士直したのだけど,コードをまず全部書き上げてから コンパイルエラーをとって実行させたら,ひとつかふたつのバグを取ったら ほぼ動作した.やっぱし前回のようなやっつけでなくきちんと設計して書くと, 全然違うなあ,と思った.

あとはシミュレータの威力に感動.シミュレータ上だと実機上よりもデバッガが 確実に動くし,信頼できる.デバッグもものすごくやりやすい. 欠点はシミュレータ側にバグがある可能性もあって (実際今回は, 「(シミュレータ編第6回)ネットワーク対応だ!」 で行ったRTL8019の仮想ドライバ実装に対応もれがあって,バッファが上書きされて MACアドレスがおかしな値になるというバグがあり,シミュレータ側に修正を入れて いる),そのへんを忘れないようにしなければならないことだけど, それを補って余りある利点がある.おすすめ.

これでIP通信はほぼ実装完了.次はいよいよTCPだ!


(2013/01/12追記:注意)

@IT MONOistの 「H8マイコンボードで動作する組み込みOSを自作してみよう!(6) :「ping」によるネットワーク通信機能を実装してみよう」 の記事の最後でpingの通信確認をしていますが,実機動作でなくシミュレータ動作の 誤記です(ごめんなさい).

実際に実機で動作させるには,まずブートローダーとOSのMakefileでのCFLAGSの -g,-Os,-O0,-DSIMULATORの指定を,無効,有効,無効,無効のように修正して ビルドします.並べると以下のようになります.

#CFLAGS += -g
CFLAGS += -Os
#CFLAGS += -O0
#CFLAGS += -DSIMULATOR
さらにrtl8019.c に対して,H8移植編その2第7回相当の 修正を入れる必要があります(でないと受信が正常に行えません).具体的には,以下の 修正を行ってください.
--- rtl8019.c~  2011-10-02 05:15:39.000000000 +0900
+++ rtl8019.c   2013-01-12 14:50:38.000000000 +0900
@@ -213,8 +213,13 @@
   *NE2000_DCR    = NE2000_DCR_F1 | NE2000_DCR_LS | NE2000_DCR_BOS;
   *NE2000_RBCR0  = 0x00;
   *NE2000_RBCR1  = 0x00;
+#if 0
   *NE2000_RCR    = 0;
   *NE2000_TCR    = 0;
+#else
+  *NE2000_RCR    = NE2000_RCR_MON;
+  *NE2000_TCR    = NE2000_TCR_ILB;
+#endif
   *NE2000_TPSR   = NE2000_TP_START;
   *NE2000_PSTART = NE2000_RP_START;
   *NE2000_BNRY   = NE2000_RP_START;
@@ -256,7 +261,11 @@
 #endif
 
   *NE2000_CR   = NE2000_CR_P0 | NE2000_CR_RD_ABORT | NE2000_CR_STP;
+#if 0 /* MONだと実機で受信できない */
   *NE2000_RCR  = NE2000_RCR_AM | NE2000_RCR_AB | NE2000_RCR_MON;
+#else
+  *NE2000_RCR  = NE2000_RCR_AM | NE2000_RCR_AB | NE2000_RCR_PRO;
+#endif
   *NE2000_CR   = NE2000_CR_P0 | NE2000_CR_RD_ABORT | NE2000_CR_STA;
   *NE2000_TCR  = NE2000_TCR_NORMAL;
   *NE2000_IMR  = 0x00;
以下が実機での動作ログです.

(PC→マイコンボードにping)

hiroaki@letsnote:~>% ping 192.168.10.16
PING 192.168.10.16 (192.168.10.16): 56 data bytes
64 bytes from 192.168.10.16: icmp_seq=0 ttl=64 time=79.725 ms
64 bytes from 192.168.10.16: icmp_seq=1 ttl=64 time=59.871 ms
64 bytes from 192.168.10.16: icmp_seq=2 ttl=64 time=59.878 ms
64 bytes from 192.168.10.16: icmp_seq=3 ttl=64 time=59.790 ms
64 bytes from 192.168.10.16: icmp_seq=4 ttl=64 time=59.795 ms
^C
--- 192.168.10.16 ping statistics ---
5 packets transmitted, 5 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 59.790/63.812/79.725/7.957 ms
hiroaki@letsnote:~>% 

(そのときのマイコンボード側での受信ログ)

command> ICMP received: c0a80a01 08 00 8cfd
ICMP received: c0a80a01 08 00 8774
ICMP received: c0a80a01 08 00 8387
ICMP received: c0a80a01 08 00 7fa1
ICMP received: c0a80a01 08 00 7bb7

unknown.
command> 

(マイコンボード→PCにping)

command> ping
ping start.
command> ICMP received: c0a80a01 00 00 08ec
ICMP received: c0a80a01 00 00 08eb
ICMP received: c0a80a01 00 00 08ea

unknown.
command> 

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