はじめて投稿いたします。
けんけんと申します。
以下環境下でpingクライアントを実装したいのですが、実装された方がいましたら実装方法を教えて頂きたいのですが?
PCと双方で疎通確認が行いたいのです。
マイコン:R5F565NEDxFB
スマートコンフィグレータコンポーネント
r_ether_rx ver1.20
r_t4_driver_rx ver1.08
r_t4_rx ver2.09
RXシリーズは初めてのプログラミングとなります。
宜しくお願い致します。
以上。
けんけんさん、こんにちは。RX64Mを使用していますが、T4ライブラリはバージョン2.08にて無事確認できたので、ご報告です。 バージョンアップがうまく出来なかった件は、プロジェクトツリーから、フォルダ一式削除しても、プロジェクトのインクルードパスに残っており、古いヘッダファイルを読んでいた事が原因でした。あとは、E1でJTAGで接続すると、クロックを最低にしないとPHY(LAN8720A)からデータが読めなくなるという現象が出ています...SDRAMも載っているので、これは基板のパターンの問題かなぁ... もし情報があれば教えて頂きたいです。 バージョンアップによる、主な変更点は、_TCBF_XXXXから、_CHINFOF_XXXXに代わっていた事です。 あとは、bool型の使用していないプロジェクトでは、エラーとなりますので、仮に動くよう適当に宣言を追加しました。 メインアプリの内容については、以前の投稿者さんが、コンソールを作られていた一部のようで、・・・の部分が無いため動きませんでしたので、 必要な部分のみ残し、動作が確認できるよう、一回だけPINGを投げる、ping_sendを作成してみました。ping_send(192,168,1,1);の様に実行し応答があると、icmp_ccep.statusがSTS_RECEVED_REPLAYとなります。 あとは、ping_commandを参考にして応答やタイムアウト、リトライなどを実装すれば良いと思います。 以下は変更内容です。変更後の行数を書いたつもりですが、間違っていたらすみません。()の中で検索して、その前後に追記・変更して頂ければと思います。 【r_t4_itcpip.h】 // 最終行(#endif /* _R_T4_ITCPIP_H */)の上に追加 /* ICMP APIs */ typedef struct t_icmp_header { // _ICMP_HDR と同じにする UB type; /* type of message */ UB code; /* code (additional info. depend on type) */ UH chksum; /* checksum of ICMP header+data */ UH id; /* message id */ UH seq; /* sequence number */ } T_ICMP_HEADER; typedef struct t_icmp_ccep { ER(*callback)(VP data, T_ICMP_HEADER *hdr , INT len); /* Callback routine */ IPaddr ipaddr; /* source address */ IPaddr dstaddr; /* destination address */ UB type; /* type of message */ UB code; /* code (additional info. depend on type) */ UH id; /* message id */ UH seq; /* sequence number */ UB *data; /* message */ INT len; /* message length */ UW timestamp; /* time stamp */ H status; ER result; } T_ICMP_CCEP; ER icmp_snd_dat(IPaddr ipaddr, IPaddr dstaddr, T_ICMP_HEADER *picmph, VP data, INT len); 【tcp_api.c】 // 最終行に追加 /* #define bool _Bool //定数を宣言したヘッダファイルをインクルードしていない場合に追加 #define false 0 #define true 1 */ // ICMP Request flag bool icmp_stat = false; // ICMP Packet Send extern T_ICMP_CCEP icmp_ccep; ER icmp_snd_dat(IPaddr ipaddr, IPaddr dstaddr, T_ICMP_HEADER *picmph, VP data, INT len) { memcpy(icmp_ccep.ipaddr, ipaddr, sizeof(IPaddr)); memcpy(icmp_ccep.dstaddr, dstaddr, sizeof(IPaddr)); icmp_ccep.type = picmph->type; icmp_ccep.code = picmph->code; icmp_ccep.id = picmph->id; icmp_ccep.seq = picmph->seq; icmp_ccep.data = (uchar *)data; icmp_ccep.len = len; icmp_stat = true; return E_OK; } 【tcp.c】 // 110行目(extern _CH_INFO *_ch_info_head;)の下に追加 /* #define bool _Bool //定数を宣言したヘッダファイルをインクルードしていない場合に追加 #define false 0 #define true 1 */ extern T_ICMP_CCEP icmp_ccep; extern bool icmp_stat; void _icmp_api(void); // 28行目(_proc_snd();)の下に追加 _icmp_api(); // 805行目(uint8_t ch;)の下に追加 uint16 len; // 934行目(if (picmph->type != _ICMP_ECHO_REQ))の下を変更 if (picmph->type != _ICMP_ECHO_REQ) { report_error(_ch_info_tbl->_ch_num, RE_ICMP_HEADER1, data_link_buf_ptr); goto _err_proc_rcv; } ↓↓↓ if (picmph->type != _ICMP_ECHO_REQ) { if(icmp_ccep.callback){ len = _ch_info_tbl->_p_rcv_buf.len - _ICMP_HLEN - _IP_HLEN_MIN; icmp_ccep.callback(picmp->data, (T_ICMP_HEADER *)picmph, len); _ch_info_tbl->flag &= ~(_CHINFOF_PEND_ICMP | _CHINFOF_SND_ICMP); rcv_buff_release(_ch_info_tbl->_ch_num); _ch_info_tbl->_p_rcv_buf.len = 0; break; } else { report_error(_ch_info_tbl->_ch_num, RE_ICMP_HEADER1, data_link_buf_ptr); goto _err_proc_rcv; } } // 最終行(#endif /* _TCP */)の上に追記 void _icmp_api(void) { uint16 sum; _ICMP_HDR *picmph_s; if(icmp_stat && (_ch_info_tbl->flag&_CHINFOF_SND_ICMP)==0){ icmp_stat = false; picmph_s = (_ICMP_HDR *)(_tx_hdr.ihdr.tip.thdr.icmph); picmph_s->type = icmp_ccep.type; picmph_s->code = icmp_ccep.code; picmph_s->chksum = 0; picmph_s->id = icmp_ccep.id; picmph_s->seq = icmp_ccep.seq; sum = _cksum((uchar *)picmph_s, _ICMP_HLEN, 0); sum = ~hs2net(sum); sum = _cksum(icmp_ccep.data, icmp_ccep.len, sum); picmph_s->chksum = hs2net(sum); _tx_hdr.hlen = _ICMP_HLEN; _tx_hdr.ihdr.tip.iph.ip_proto_num = _IPH_ICMP; _cpy_ipaddr(_tx_hdr.ihdr.tip.iph.ip_dst, icmp_ccep.dstaddr); _cpy_ipaddr(_tx_hdr.ihdr.tip.iph.ip_src, icmp_ccep.ipaddr); _ip_snd(icmp_ccep.data, icmp_ccep.len); } } 【アプリ】 #define STS_WAIT_FOR_RESPONCE 1 #define STS_RECEVED_REPLAY 2 #define STS_PRINTED_RESULT 3 // 初期値の設定 T_ICMP_CCEP icmp_ccep = { NULL, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, 0, 0, 0, 0, NULL, 0, 0 }; static T_ICMP_HEADER icmph = { 8, 0, 0, 0x0001, 0 }; unsigned char ping_msg[32]; static ER ping_callback(VP data, T_ICMP_HEADER *hdr , INT len) { if(hdr->seq == icmp_ccep.seq){ icmp_ccep.status = STS_RECEVED_REPLAY; if(len!=icmp_ccep.len || memcmp((char *)data, (char *)icmp_ccep.data, icmp_ccep.len)!=0){ icmp_ccep.result = -1; } else { icmp_ccep.result = E_OK; } } return E_OK; } short ping_send(unsigned char ip1,unsigned char ip2,unsigned char ip3,unsigned char ip4){ ER ercd; IPaddr dstaddr; dstaddr[0] = ip1; dstaddr[1] = ip2; dstaddr[2] = ip3; dstaddr[3] = ip4; icmp_ccep.callback = ping_callback; icmp_ccep.timestamp = 0; //PINGを送信した時刻 icmp_ccep.status = STS_WAIT_FOR_RESPONCE; icmp_ccep.result = E_OK; ++icmph.seq; ercd = icmp_snd_dat(tcpudp_env[0].ipaddr, dstaddr, &icmph, (VP)ping_msg, sizeof(ping_msg)); if(ercd){ icmp_ccep.callback = NULL; return 0; } return 1; } int ping_command(int argc, char *argv[]) { /* この関数はPINGの繰り返しと画面表示を行う独自の内容なので、使わない */ }
けんけんさん、こんにちは。こちらで確認した内容は、lan_open()の後、メインループで_process_tcpip();を実行している状態で、定期的にping_sendをコールしています。Wiresharkでの挙動は、1回目はARPのみ、2回目からPINGが出ていました。ちなみに、ライブラリのソースは改造とデバッグがし易い様、T4_srcをプロジェクトに追加(不要なファイルは除く)して、「使用するライブラリファイル」からは削除しています。参考になるかわかりませんが、T4の設定画面を添付いたします。