しばらくシミュレータ対応を進めていたのだけど,シミュレータでネットワーク通信が できるようになったので,そろそろ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のソースコードについてだが, 修正点多すぎてここではいちいち説明しないけど,以下の動作ができます.
(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だ!
@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>