MLAのFrameworkでTCP/IPを試して見るその2
(PING"エコー要求"と"エコー応答")

〔PICの動かせ方入門に戻る〕
〔その1〕   〔TELNET〕 〔SMTP〕 〔XC16編〕 〔TCPclient〕 〔TCPserver〕 〔HTTPserver〕


前ページの"その1"では、FrameworkのTCP/IPスタックファイルの話と、tcpipプロジェクト作成方法の
話を書きましたので先ずはそちらからご覧下さい。
このページでは、ICMPモジュールを 使ってPINGコマンドの”エコー要求(Echo)”と
エコー応答(Echo Reply)”の基本動作を実験してみます。

ここで、”データのカプセル化”につてこちらこちらを読んでおきましょう。
これはデータの流れにおいて、各層でのプロトコルに従いデータにヘッダを追加していく話です

カプセル化のイメージ図
こんな感じで各層のプロトコル仕様により各層のヘッダ(荷札)が追加され
ユーザのデータは運ばれて行きます。
物理層の荷札はMACアドレス(ここも)
インターネット層の荷札はIPアドレス
トランスポート層の荷札はポート番号
イーサネットのフレーム構成」も見ておきましょう。


これがこのページで実験する必要最小限の構成でのモデルです。
インターネット層
  ICMP  
IP
 ARP
  Stack Task 
物理層
ENC28J60

Stack Task
 着信パケットのチェックを行い、上層のスタックモジュールにルーティングします。
 このタスクが"ENC28J60.c"のドライバーを呼び出す事になります。
 タイムリーな応答を確保するために、この関数を定期的に呼び出さなければなりません。
 なのでぇ、アプリケーションを作成する場合は必要最小限のDelayを使い、ステートマシン的な
 小刻みな処理を施す必要が有ります。

ARP
 インターネットの世界ではIPアドレスで送受信を行っていますが、インターネットは
 イーサネットプロトコルを利用しているので相手先のMACアドレスを知らないと送る事が出来ません。
 でぇ、このIPアドレスからMACアドレスの交換を行ってくれるのがARPです。
 交換の仕方はこちら「アドレス解決とARP」を参照下さい。
 通知されたMACアドレスは通常キャッシュに記憶されるのですが、このARPにはキャッシュ無りません

IP
 TCP/IPのデバイス間でIPアドレスによるデータの送受信を行います。
 単純にパケットの交換のみが役割で、データの分割も行う。
 IPプロトコルのフレームフォーマットやヘッダ内容はこちらこちらを参照しましょう。

ICMP
 IPは通信異常が発生しても報告する機能が無いのでこれを補う為にICMPで通信エラーや
 ネットワークの状況を通知してくれるらしい。
 ICMPには色々な要求メッセージが有る様だが、TCP/IPスタックのICMPは”エコー要求”と
 ”エコー応答”のみっぽいです。
 ICMPのフレームフォーマットは「ICMPとPINGコマンド」を参照しましょう、
 ICMPヘッダについてはこちらも参照しましょう。

《実験回路》

ENC28J60モジュールのピン構成
ENC28J60モジュール VCC
電源3.3V パケット転送中動作電流180mA
十分に流せる電源を準備しましょう。
GND
グランド
RESET
LOWでリセットなので通常はHIGH
CS
SPIのチップセレクト入力ピン
SCK
SPIのクロック入力ピン
SI
SPIのデータ入力ピン
SO
SPIのデータ出力ピン
WOL
ウェイクアップ用割り込み出力
新チップはNCになっている。
INT
割り込み出力ピン
CLKOUT
クロック出力ピン
灰色背景色のピンは今回利用しません。


実態配線図

LCD表示 器についての配線等の詳細はこちらのページを参照下さい。
ここでは18F25K22を使っていますがぁ、後後の実験を考えるとぉ18F26K22の方がプログラム容量が
倍有るのでそちらをお勧めします。

ENC28J60のRESETピンについて
RESETピンはPICのRC1ピンに接続されていますが、これは"ENC28J60,c"の初期化関数(MACInit)でHIGHを出力しているだけ なので、直接VDDに配線すればPICピンが1本利用可となります。
その際は、"system_config.h"の"#define ENC_RST_IO"をコメントにします。

回路電源について
ENC28J60モジュールが3.3Vなので回路電源は3.3Vで統一していますが、
ENC28J60自体の消費電流がパケット転送中で最大180mA、転送していない時で120mAと
結構電気食いで変動も激しいです。

当初、こちらの前の型にACアダプタ(何時もの実験スタイルです)接続で行っていたのですがぁ...
動作でぇパケット受信したらPICがリセットするのです、でぇ、"ENC28J60.c"のXC8化が
上手く行ってないのかぁとか、リセットする場所を調べたりとかぁ、
もお色々ハマリまくりでぇ丸4日費やしもうダメぇと諦めた頃ふと、あ、電源では?と気付いた次第です。

でぇ、使った電源を計測(デジタルテスター)したら120mA程しか出力出来ていないらしく、
でぇ、使っているACアダプタ出力に3V切替が有り計測したら3.44V程出力するので直接そのまま
使う事にして転送していない時に計測したら129mA程で、転送中は表示されなく不明でした

更に、PICのコンフィギュレーション、BOREN=OFF(電源電圧降下常時監視機能は切る)も
施したら何とか動作する様になったとさ、
ですから 十分に流せる安定化された電源を準備しましょう

《ダウンロードファイルについて》

↓ここからプログラムソースをダウンロードして下さい。
PING_ENC28J60.zip
ファイルの説明とプロジェクトの作成方法は”その1”を参照下さい。
MPLAB X IDE v3.50MPLAB(R) XC8 C Compiler Version 1.40コンパイラを使用しています。

※ PINGのサンプルは、"C:\microchip\mla\v2016_11_07\apps\tcpip\wifi_demo_app\
  firmware\src" フォルダーの"ping_demo.c"ファイルから作成しました。

《実験1》

実験1は固定IPアドレスを指定し てのPING”エコー要求”と”エコー応答”を行って見ます。

必要最小限の構成でのモデル(上記参照)での実験です。

@ "tcpip_config.h"のMACアドレス・IPアドレ ス・サブネットマスクは”その1”を見て自分ちの
  ネット環境に合わせて設定は完了していますね。

  MY_DEFAULT_GATE_BYTE
  デフォルトゲートウェイの所も設定を行って下さい、このIPアドレス宛に”エ コー要求”します。
  ここでの例は"192.168.3.1"と指定した ので ここにPINGされます。

A プログラムをコンパイルしPICに書き込みましょう。
  ”framework/tcpip/src/common/helpers.c:1370: warning: (1496) arithmetic on pointer to void
   yields Undefined Behavior”
  とワーニングが出るかもですがぁ、気にしなくても良いでしょう、たぶん。
  この実験1コンパイルでの使用メモリは「Program=10686byte Data=314byte」です。

B ENC28J60をネットワークに接続し、回路電源を入れましょう。
  (私はYAHOO!プロバイダーのトリオモデムのAPに繋いでの 実験です)

C LCDの1行目に[  Test to PING  ]が表示されます。

D でぇ、3秒後に処理開始です、LEDが1秒毎に点滅します
  LCDの2行目に"tcpip_config.h"で設定した IPアドレスが表示されます。
  [ My IP Address  ]
  [192.168.3.105    ]  ←は自分が設定したIPアドレスが表示されます がぁ以下はこれで説明

E PCのコマ ンドプロンプト画面を起動させ”ping 192.168.3.105”と実行させて下さい。
PING実行画面
 とぉ、こんな感じにPICが応答を返し表示されるでしょう。

F 次は回路のスイッチをポチットぉ押して見て下さい。

PING要求実行LCD画面" tcpip_config.h"ネットワークアドレス指定オプションの
デフォルトゲートウェイの所に設定しているIPアドレス宛に
"PINGエコー要求"がされます。

応答が有れば、左の様に応答時間が表示されますが、それ以外の
場合は下記のメッセージが表示されます。

 [PING timed out  ]   時間切れリクエストはタイムアウトしました。
 [Can't resolve IP ]   解決できないDNS/IPアドレス。

これで必要最小限のモジュール構成でのネット接続は出来た事になります。
ここまで来れた人はまず一安心、おめでとうございます。""ハ(゚∇゚*)パチパチ

《実験2》

実験2は、DHCPサーバーからIPアドレ スを割り振って貰う実験を行います。

これがDHCP追加のモデルです。
DHCP追加の構成モデル

DHCP
 今回追加するのは、"DHCPクライアント"部分のみで す、"DHCP サーバー"側は含まれません。
 IPアドレスを得る為にDHCPサーバーへ「DISCOVER」パケットの発行処理を行います。
 又、DHCPのメッセージフォーマットはこちらを参照下さい。

UDP
 送信完了等の確認を行わない比較的単純なプロトコル(こち らも見ておこう)。
 通信中のデータ異常への対応などは上位のプロトコル(アプリケーション層)で行います。
 信頼性を重視する必要が無く、速度を重視するアプリケーション で使用されます
 信頼性を重視する場合は"TCPプロトコル"を使用します

"tcpip_config.h"の変更
#define STACK_USE_ICMP_SERVER   // ICMP(PING)はサーバ(Ping query応答)機能を実装する
#define STACK_USE_ICMP_CLIENT // ICMP(PING)はクライアント(送信)機能を実装する

#define STACK_USE_DHCP_CLIENT  // IPアドレス及びその他のパラメータを取得する為のDHCPライアントの実装
"STACK_USE_DHCP_CLIENT"の行コメントを外し "DHCPクライアント"モジュールを生かします、
これにより"UDP"モジュールも追加されます。

追加されるファイル構成

dhcp_client.c DHCP クライアントプロトコルのモジュールファイル(RFC 2131)(RFC 2132)
Dynamic Host Configuration Protocol
DHCP対応ネットワーク上の自動IPアドレス、サブネットマスク、ゲートウェイアドレス、DNSサーバーアドレス、およびその他の構成パラメータを提供 します。
udp.c
UDPプ ロトコルのモジュールファイル(RFC 768)
User Datagram Protocol
アプリケーション・データグラム(パケット)指向のデータの信頼性が低く、
最小遅延のトランスポートを提供します。



@ プログラムを再コンパイルしPICに書き込みましょう。
  この実験2コンパイルでの使用メモリは「Program=17112byte Data=314byte」です。
  PIC18F25K22では、52%もプログラムメモリを消費しました。

A ENC28J60をネットワークに接続し、回路電源を入れましょう。

DHCPからのIPアドレス割り当て表示画面 B 実験1では設定したIPアドレス[192.168.3.105   ] が
  表示されたと思いますが、今度はDHCPサーバーから
  割り振られたIPアドレス[192.168.3.5    ] を表示
  しています。
  (表示されるアドレスは環境により異なりますよ、念の為)

C PCのコマンドプロンプト画面を起動させ”ping 192.168.3.5”と実行させて下さい。
  応答が有ると思います、因みに”ping 192.168.3.105”では応答がないでしょう。

これでDHCPサーバーからIPアドレスが割り当てられる事が解ったと思います。
尚、IPアドレス、サブネットマスク、ゲートウェイアドレス、DNSサーバーアドレス等のデータを自分で
設定するのでDHCP機能はいらなければ"DHCPクライアント"モジュールは取り外しても良いでしょう。

《実験3》

実験1では、デフォルトゲートウェイの所に設定したIPアドレス宛に"PINGエコー要求"がされました。
実験3では、ホスト名(ドメイン名)で"PINGエコー要求"を行って見ます。

これがDNS追加のモデルです。
DNS追加の構成モデル

DNS
 今回追加するのは、"DNSクライアント"部分のみで す、"DNSサーバー"側は含まれません。
 DNSは名前解決機能が有り、ホスト名からIPアドレスに変換する為にDNSサーバーへ
 問い合わせパケット(正引き) の発行処理を行います。

"tcpip_config.h"の変更
#define STACK_USE_ICMP_SERVER   // ICMP(PING)はサーバ(Ping query応答)機能を実装する
#define STACK_USE_ICMP_CLIENT // ICMP(PING)はクライアント(送信)機能を実装する

//#define STACK_USE_DHCP_CLIENT  // IPアドレス及びその他のパラメータを取得する為のDHCPライアントの実装
#define STACK_USE_DNS_CLIENT // ホスト名文字列をIPアドレスに解決する為のDNSクライアントの実装
"STACK_USE_DHCP_CLIENT"の行コメントを一旦コメントを付けてモジュールを外します。
"STACK_USE_DNS_CLIENT"の行コメントを外し "DNSクライアント"モジュールを生かします、
これにより"UDP"モジュールも追加されます。

追加されるファイル構成

dns_client.c DNS クライアントプロトコルのモジュールファイル(RFC 1035)
Domain Name System
ホスト名からIPアドレスへの変換を提供します
udp.c
上記参照


@ プログラムを再コンパイルしPICに書き込みましょう。
  この実験3コンパイルでの使用メモリは「Program=17744byte Data=314byte」です。
  PIC18F25K22では、54%もプログラムメモリを消費しました。

A ENC28J60をネットワークに接続し、回路電源を入れましょう。

B 起動時のMy IPアドレスはDHCPを外したので[192.168.3.105    ]ですね。

C 回路のスイッチをポチットぉ押して見て下さい。

DNSでの名前解決機能実験表示左図の様に”ww1.microchip.com”のホスト名で
"PINGエコー要求"が行われました。
(表示は16文字までなので"m"が有りません)


"TestPING.c"ファイルに#define HOST_TO_PING "ww1.microchip.com"
が記述して有るので他のホスト名にしたい場合は書換えて下さい。

これでDNSの名前解決が出来ましたね。

《実験4》

実験1・実験2では、PCからPINGする場合にIPアドレスを指定(ping 192.168.3.105)して行いましたね。
"tcpip_config.h"ファイルに
#define MY_DEFAULT_HOST_NAME            "PIC18F26K22"  // 15文字までの半角英数字
とホスト名を登録していたと思います。
なのでぇ実験4では、このホスト名 (NetBIOS名)を指定して実験を行って見ます。

これがNBNS追加のモデルです。
NBNS追加の構成モデル

NBNS
 PCから名前の問い合わせパケットが有った場合に応答する為に"NBNS" モジュールで行います。
 ここでNetBIOSについて、ここここのページを読んで置きましょう。

"tcpip_config.h"の変更
#define STACK_USE_ICMP_SERVER   // ICMP(PING)はサーバ(Ping query応答)機能を実装する
#define STACK_USE_ICMP_CLIENT // ICMP(PING)はクライアント(送信)機能を実装する

//#define STACK_USE_DHCP_CLIENT  // IPアドレス及びその他のパラメータを取得する為のDHCPライアントの実装
//#define STACK_USE_DNS_CLIENT // ホスト名文字列をIPアドレスに解決する為のDNSクライアントの実装
#define STACK_USE_NBNS // NBNSホスト名ブロードキャストクエリに応答するNetBIOSネームサービスサーバの実装
"STACK_USE_DHCP_CLIENT"と"STACK_USE_DNS_CLIENT"の行コメントを一旦コメントを付けてモジュールを外しま す。
"STACK_USE_NBNS"の行コメントを外し"NetBIOSネームサービスサーバー"モジュー ルを
生かします、これにより"UDP"モジュールも追加されます。

追加されるファイル構成

nbns.c NBNS プロトコルのモジュールファイル(RFC 1002)
NetBIOS Name Service (NBNS)
ボードへのホスト名割り当てを許可するNBNSの名前要求に対応します。
即ち、同じIPサブネット上のノードが、IPアドレスではなくボードにアクセスする為にホスト名を使用する事を可能にする。
udp.c
上記参照


@ プログラムを再コンパイルしPICに書き込みましょう。
  この実験4コンパイルでの使用メモリは「Program=14190byte Data=314byte」です。
  PIC18F25K22では、43%もプログラムメモリを消費しました。

A ENC28J60をネットワークに接続し、回路電源を入れましょう。

B 起動時のMy IPアドレスはDHCPを外したので[192.168.3.105    ]ですね。

C PCのコマ ンドプロンプト画面を起動させ”ping PIC18F26K22”と実行させて下さい。
  (実際に使っているPICは18F25K22なんですがぁね...)
PINGホスト名での実行画面
 とぉ、こんな感じにPICが応答を返し表示されるでしょう。

これで、ホスト名(NetBIOS名)による接続が出来ました。

《ぜ〜んぶコンパイルしたらぁ》

ICMP/DHCP/DNS/NBNSを全部一緒にコンパイルしたら

ア プリケーション層
DHCP
DNS
NBNS
ト ランスポー ト層 
UDP
インターネット 層
IP (ICMP)
Stack Task
物理層
     ENC28J60

使用メモリは「Program=22910byte Data=314byte」です。
PIC18F25K22では、70%もプログラムメモリを消費しました。

因みに、これに”SMTPクライアント”と”TCP”モジュールを追加してコンパイルして見たら
メモリ不足でコンパイル不能でした、次回からはPIC18F26K22に交換して実験を続けたいと思います。

《その他》

PINGの実験風景
実験の風景です。
PICの電源引き込み部分に100uFの電解コンデンサーも取り付けている、
これで大分安定して動作しています。

ε-(´∀`*) ふぅ、一時は諦め掛けたがやっとここまで出来ました。
次回はTELNETサーバーでもやってみます。



【きむ茶工房ガ レージハウス】
Copyright (C) 2006-2017 Shigehiro Kimura All Rights Reserved.