pingクライアントについて

はじめて投稿いたします。

けんけんと申します。

以下環境下でpingクライアントを実装したいのですが、実装された方がいましたら実装方法を教えて頂きたいのですが?

PCと双方で疎通確認が行いたいのです。

マイコン:R5F565NEDxFB

スマートコンフィグレータコンポーネント

r_ether_rx ver1.20

r_t4_driver_rx ver1.08

r_t4_rx ver2.09

RXシリーズは初めてのプログラミングとなります。

宜しくお願い致します。

以上。

Parents
  • けんけんさん、こんにちは。
    PINGについては、ICMPで検索すると見つかる場合があります。
    過去に、作られた方がみえるようです。
    japan.renesasrulz.com/.../m3s-t4-tiny
  • HiRoSan。こんにちは。けんけんです。

    情報有難うございます。
    実は私も投稿する前に教えて戴いたURLの内容を参考に挑戦したのですが、
    バージョン違いによりなかなか「***行目」というところが一致しない点と
    コンパイルした結果エラーが何点か発生してしまい
    途中で妥協してしまいました。
    再度挑戦してみようと思います。
    現バージョンでの情報がありましたらお願いいたします。
  • けんけんさん、こんにちは。
    既に情報は見つけてみえたんですね。失礼しました。
    Ver1.8のファイルも探してみましたが、合致するものは見つかりませんでした。
    以前、2.08にてデバッグを行っていたソースがあるのですが、単純に2.09に置き換えようと思ったところ、KeepAlive関係が追加されており動きませんでした。(スマートコンフィグレータで更新しても2.08のままで、更新方法がいまいちわかりませんでした)
    NW関係を触る予定はあるものの、すぐには試せない為、時間があいたら試してみたいと思います。
  • HiRoSanさん。こんにちは。けんけんです。

    返信ありがとうございます。
    私の方もコンポーネントには更新はなく追加と削除しかない為、1回削除をしてから追加したか、
    ちょうどPCの更新した時期でもあり新たに再度プロジェクトを作成したような気がします。

    ping送信の件、お時間が空いた時で宜しいので宜しくお願い致します。
Reply
  • HiRoSanさん。こんにちは。けんけんです。

    返信ありがとうございます。
    私の方もコンポーネントには更新はなく追加と削除しかない為、1回削除をしてから追加したか、
    ちょうどPCの更新した時期でもあり新たに再度プロジェクトを作成したような気がします。

    ping送信の件、お時間が空いた時で宜しいので宜しくお願い致します。
Children
  • けんけんさん、こんにちは。
    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の繰り返しと画面表示を行う独自の内容なので、使わない */
    }

  • HiRoSanさん。こんにちは。

    詳細な情報有難うございます。
    解りやすく助かります。

    まだping送信には至っていないのですが、済みません。もう少しアドバイスの方をお願いいたします。

    下記はHiRoSanさんの情報を基に実施した内容となります。
    1.ライブラリソースコードに変更内容のコードを追加、再コンパイル行いました。
      エラーは発生しませんでした。
    2.ライブラリファイル
      (T4_Library_ether_ccrx_rxv1_big.lib/T4_Library_ether_ccrx_rxv1_little.lib)が日付更新されました。
    3.CS+「CC-RX(ビルドツール)」の共通オプション「使用するライブラリファイル」に   T4_Library_ether_ccrx_rxv1_big.libの登録を確認しました。
    4.PCとRX65Nマイコン基板をLANで接続。(PC側、マイコン側共に固定IP)
    4.アプリケーションにてlan_open()関数の後にping_sendをコール。
    5.wiresharkにてパケットを確認したのですが、出力されませんでした。

    現状ではPCとマイコンはudpによる送受信は行えている状態です。PHYは動作しております。
    スマートコンフィグレータの設定等は関係しているのでしょうか、
    もし差し支えなければスマートコンフィグレータの画面(コンポーネントr_t4_rx等)を開示して戴けると助かります。

    宜しくお願い致します。
  • けんけんさん、こんにちは。
    こちらで確認した内容は、lan_open()の後、メインループで_process_tcpip();を実行している状態で、定期的にping_sendをコールしています。
    Wiresharkでの挙動は、1回目はARPのみ、2回目からPINGが出ていました。
    ちなみに、ライブラリのソースは改造とデバッグがし易い様、T4_srcをプロジェクトに追加(不要なファイルは除く)して、「使用するライブラリファイル」からは削除しています。
    参考になるかわかりませんが、T4の設定画面を添付いたします。


  • HiRoSanさん。こんにちは。

    済みません。wiresharkにパケットが出てこなかったのは、PHYがLINKupする前にping送信をしていたからでした。済みません、よく確かめませんでした。
    HiRoSanさんの様にlan_open()の後、メインループにて、定期的にping_sendをコールする様にして、無事ping送信が行えました。
    また、PCからの応答受信にてstatic ER ping_callback(VP data, T_ICMP_HEADER *hdr , INT len)が呼ばれる事を確認しました。
    スマートコンフィグレータT4の設定は何も変更せず以前のままで使用しています。

    色々アドバイスを戴き助かりました。
    有難うございました。