MLAのFrameworkでTCP/IPを試して見るその2
(PING"エコー要求"と"エコー応答")
〔PICの動かせ方入門に戻る〕
〔その1〕
〔TELNET〕
〔SMTP〕
〔XC16編〕
〔TCPclient〕
〔TCPserver〕
〔HTTPserver〕
前ページの"その1"では、FrameworkのTCP/IPスタックファイルの話と、tcpipプロジェクト作成方法の
話を書きましたので先ずはそちらからご覧下さい。
このページでは、ICMPモジュールを
使ってPINGコマンドの”エコー要求(Echo)”と
”エコー応答(Echo Reply)”の基本動作を実験してみます。
ここで、”データのカプセル化”につてこちらとこちらを読んでおきましょう。
これはデータの流れにおいて、各層でのプロトコルに従いデータにヘッダを追加していく話です
インターネット層
|
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モジュールのピン構成
|
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.50 とMPLAB(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は固定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”と実行させて下さい。
とぉ、こんな感じにPICが応答を返し表示されるでしょう。
F 次は回路のスイッチをポチットぉ押して見て下さい。
"
tcpip_config.h"ネットワークアドレス指定オプションの
デフォルトゲートウェイの所に設定しているIPアドレス宛に
"PINGエコー要求"がされます。
応答が有れば、上の様に応答時間が表示されますが、それ以外の場合は下記のメッセージが表示されます。
[PING timed out ] 時間切れリクエストはタイムアウトしました。
[Can't resolve IP] 解決できないDNS/IPアドレス。
これで必要最小限のモジュール構成でのネット接続は出来た事になります。
ここまで来れた人はまず一安心、おめでとうございます。""ハ(゚∇゚*)パチパチ
実験2は、DHCPサーバーからIPアドレ
スを割り振って貰う実験を行います。
これが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をネットワークに接続し、回路電源を入れましょう。
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クライアント"モジュールは取り外しても良いでしょう。
実験1では、デフォルトゲートウェイの所に設定したIPアドレス宛に"PINGエコー要求"がされました。
実験3では、ホスト名(ドメイン名)で"PINGエコー要求"を行って見ます。
これが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 回路のスイッチをポチットぉ押して見て下さい。
左図の様に”ww1.microchip.com”のホスト名で
"PINGエコー要求"が行われました。
(表示は16文字までなので"m"が有りません)
"TestPING.c"ファイルに#define HOST_TO_PING "ww1.microchip.com"
が記述して有るので他のホスト名にしたい場合は書換えて下さい。
これでDNSの名前解決が出来ましたね。
実験1・実験2では、PCからPINGする場合にIPアドレスを指定(ping 192.168.3.105)して行いましたね。
"tcpip_config.h"ファイルに
#define
MY_DEFAULT_HOST_NAME
"PIC18F26K22" // 15文字までの半角英数字
とホスト名を登録していたと思います。
なのでぇ実験4では、このホスト名
(NetBIOS名)を指定して実験を行って見ます。
これが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なんですがぁね...)
とぉ、こんな感じにPICが応答を返し表示されるでしょう。
これで、ホスト名(NetBIOS名)による接続が出来ました。
《ぜ〜んぶコンパイルしたらぁ》
ICMP/DHCP/DNS/NBNSを全部一緒にコンパイルしたら
ア
プリケーション層
|
DHCP
|
DNS
|
NBNS
|
ト
ランスポー
ト層
|
UDP
|
インターネット
層
|
IP
(ICMP)
|
Stack
Task |
物理層
|
ENC28J60
|
使用メモリは「Program=22910byte
Data=314byte」です。
PIC18F25K22では、70%もプログラムメモリを消費しました。
因みに、これに”SMTPクライアント”と”TCP”モジュールを追加してコンパイルして見たら
メモリ不足でコンパイル不能でした、次回からはPIC18F26K22に交換して実験を続けたいと思います。
《その他》
実験の風景です。
PICの電源引き込み部分に100uFの電解コンデンサーも取り付けている、
これで大分安定して動作しています。
ε-(´∀`*)
ふぅ、一時は諦め掛けたがやっとここまで出来ました。
次回はTELNETサーバーでもやってみます。
【きむ茶工房ガレージハウス】
Copyright (C) 2006-2020 Shigehiro Kimura All Rights Reserved.