uIP TCP/IPについて

先ごろ(だいぶ前ですが)ルネサスサイトから uIP TCP/IP Protocol Stack Demostration Document number:R01AN0169EU0100 Ver 1.01 NOTEs: * The demostration directory structure is explained in the application note. * This application note supports RX62N and the demostration project runs on RSK+RX62N. UIPのサンプルを入手しましてSH7670へ移植しました、その結果とても良好な結果を得ましたので報告します 自前のソースでTCP/IPを実装して稼動させていましたがよく応答ができなくなったりしていました いろいろな遷移状態でわけがわからないような(たぶんプロトコルが十分でない)遷移もありました UIPにすると必ず応答して、応答不良などまだ経験がありません、 ただこのUIP長い(大きい)データ転送には弱いんです、”どうしてこんなに時間がかかるの”というぐらい なにか説明ではACKが200mセコンドウェイト方式を採用しているからだとか これの速度はもっと速くはならないものでしょうか? IWIPなど聞きますが、UIPと比べてどうなのでしょうか、IWIPのほうがいいのでしょうか?
Parents
  • こんにちは、ルネサスマイコン(RXマイコン中心ですが)でTCP/IP関連をいろいろ実験しておりますシェルティと申します。

    TCP/IPですが、複雑怪奇な仕様であり、スクラッチ開発となると相当な難易度ですね。

    実験/研究レベルならスクラッチ開発もありかもしれませんが、量産製品に適用となると、

    第一にネットワーク関連ソフトを組み込みマイコン向けに製品化しているソフトウェアハウス製のものがおすすめです。

    例えば、図研エルミック殿やデータテクノロジー殿、ユビキタス殿などの組み込み用TCP/IPが有名です。

    ルネサス製でも組み込み用TCP/IP M3S-T4-Tinyというのが有償製品として提供されています。(SH2A用の無償ダウンロードもあるようです)

    http://japan.renesas.com/mw/t4

     

    第二に組み込み用OSに内包されているTCP/IP機能を使うのも良いです。

    (ここでいう組み込み用OSはリアルタイムOSではなく、組み込み用Linuxを指します)

     

    第三にuIPやlwIP等のオープンソース系のコードを頑張って量産製品に適用する道です。

    第四にスクラッチ開発でTCP/IPを手作りする道です。

    第三・第四の道は技術力に自信が有る場合におすすめですね。

    安く仕上げられるというメリットも捨てがたいと思います。

    -------

    さて、uIPで大きいデータ転送に弱い件ですが、uIPのTCP処理の実装に問題があります。

    lwIPでも私が調査した限り同様の問題を含んでいます。

    組み込み用TCP/IP M3S-T4-TinyもRXマイコン用パッケージにて、最近ソースコードが公開されたので中の実装を確認したところ、

    uIPやlwIPよりはマシですが、もう一段の改善が必要といったところです。

    各TCP/IPを比較すると以下の通りです。

    uIP or lwIP : TCPの送信アルゴリズムが貧弱。データ送信1回につき1個のACKが戻ってくることを期待している。

             多くの一般的なTCP/IPはTCPデータ受信時は2個データを受信する or 1個データ受信し200ms経過後タイムアウトしACKを返す実装になっている。

             その結果、毎回タイムアウトが発生し1秒に5回のデータ転送しか実現出来ない。

    組み込み用TCP/IP M3S-T4-Tiny : TCPの送信アルゴリズムが少し貧弱。データ送信は2個セットでACKが戻ってくることを期待している。

             多くの一般的なTCP/IPはTCPデータ受信時は2個データを受信する or 1個データ受信し200ms経過後タイムアウトしACKを返す実装になっている。

             その結果ACKがすぐ戻ってくるネットワーク環境(LAN)においては転送速度に問題は発生しないが、

             ACKがすぐに戻ってこないネットワーク環境(WAN)においては転送速度がACKが返ってくる時間に律速する。

             ACKが返ってくるまで200msかかる(東京-北米西海岸等)通信をする場合は、uIP or lwIPと変わらない程度の通信速度に落ちる。

             ※ローカル環境ではSH7216@200MHz で、TCP送受信が60Mbps程度出せることを確認しました。(RX62N@100MHz では30Mbps程度確認)

    -----

    これは組み込み用TCP/IPが多くの場合、RAM容量に制限の多いマイコンでの動作を期待しているため、

    送信用/受信用のバッファを多く持たないことに起因します。

    TCPの規格上、お互いに受信用のバッファサイズ(受信ウィンドウと呼ばれます)を常にTCPヘッダの特定16bitエリア(0xffff=最大64KB)に載せて

    通知し合っているわけですが、上述したTCP/IPたちはここにTCPパケット1個分(=1460バイト)の容量を設定しているのです。

    #組み込み用TCP/IP M3S-T4-Tinyではここが可変になっていて柔軟にチューニングが効くようにはなっています。

    その上、送信アルゴリズムも上述した通り貧弱ですのでいずれにしても大きなデータ通信には向きません。

    -----

    長くなりました。

    結論ですが、量産製品にTCP/IP機能を付ける目的であれば、有償のTCP/IP製品をお求めになるのが良いかと思います。

    とにかくまず実験して感触を掴んでみたい/通信速度が気になる/LANでしか通信しない、ということであれば、

    SH2A用の組み込み用TCP/IP M3S-T4-Tinyを使って実験されるのが良いかと思います。

    ただ、ソフトは無償ダウンロードがありますが、SH7216の評価ボードとE10Aエミュレータが必要となり、ちょっと実験してみるのには敷居が高そうですね。

    (TCP/IP処理部分はSH7670でも動作するでしょうけれど、サンプル全体がSH7216用に作られているため、

     Etherドライバ付近とボード周りの設定プログラム、スタートアップ等を調整してあげる必要はありそうです)

    もちろん、せっかくuIPをSH7670に移植されたのですから、大きなデータ通信については目をつむり、そのまま使用し続ける案も十分に有りと思います。

    以上です。

     

     

  • すみません、少し書き漏れました。

    一般的なTCP送信アルゴリズムは、「通信相手の受信ウィンドウサイズに空きがあればACKが返ってこなくてもお構いなしに送信する」です。

    このように実装するためには、通信相手の受信ウィンドウサイズの最大値(0xffff=64KB)の容量の送信バッファが必要です。

    しかも、通信相手が複数同時に居る場合は通信相手の数分だけ64KBの送信バッファが要ります。もちろん受信ウィンドウも要ります。

    従って、多くの(オープンソース系)組み込み用TCP/IPは多くのマイコンで動作させることを優先し、

    バッファサイズを制限し通信速度を犠牲にしたのだと思います。

    組み込みソフトを専業でやっているソフトウェアハウスのTCP/IPの場合、この辺りが柔軟に設定できるものがあると聞きますので

    本格的に量産製品を作られる場合は一度ソフトウェアハウスに相談してみるのが良いかと思います。

     

     

  • シェルティです、すみません訂正です。

    <Etherドライバ世代4>はRXマイコン用のBSPが前提のコードが有り

    これをSH7216 or SH7670に移植するのは少し骨が折れそうです。

    <Etherドライバ世代3>であればiodefine.h の差分だけ何とかしてあげれば

    RXマイコン用→SH7216 or SH7670用に移植が出来そうな印象を受けました。

    以上です

  • シェルティ さん、なるほどこれから苦労しそうということですね

    一応変更したところですが、自己流に改造してしまったというところですが

    ///////////////////////////////////////////////////////////////////////

    //etherから呼び出す

    ///////////////////////////////////////////////////////////////////////

    t4_H lan_read( t4_B **buf )

    {

    t4_H return_code;

    return_code=(t4_H)lan_recv(lan_buf); //etherからデータを受信する

    if(return_code > 0){

    //有効なデータを読み込んだ

    *buf = (t4_B*)lan_buf;

    t4_stat.t4_rec_cnt++;

    t4_stat.t4_rec_byte+=return_code;

    }else{//有効なデータは受信しなかった

    return_code = -1;

    }

    return return_code;

    }

    ///////////////////////////////////////////////////////////////////////

    //etherから呼び出す end

    ///////////////////////////////////////////////////////////////////////

    ///////////////////////////////////////////////////////////////////////

    //etherから呼び出す

    ///////////////////////////////////////////////////////////////////////

    t4_H lan_write( t4_B *header , t4_H header_len, t4_B *data , t4_H data_len)

    {

    t4_H return_code;

    if (header_len+data_len > 1514 || header_len+data_len <= 0){

    return -5; // Return code "-5" notifies "data transmission fail" to T4.

    }

    memcpy(lan_buf, header, header_len);

    memcpy(lan_buf + header_len, data, data_len);

    //etherにデータを送信する

    return_code=(t4_H)lan_send(lan_buf,header_len+data_len);

    if (return_code < 0){

    return -5;//登録失敗

    }else{

    //登録成功

    t4_stat.t4_snd_cnt++;

    t4_stat.t4_snd_byte += (header_len + data_len);

    }

    return return_code;

    }

    ///////////////////////////////////////////////////////////////////////

    //etherから呼び出す end

    ///////////////////////////////////////////////////////////////////////

    ///////////////////////////////////////////////////////////////////////

    //tcp_apiから呼び出す

    ///////////////////////////////////////////////////////////////////////

    //TCP/IP処理関数の周期起動の制御

    //パラメータcycactにしたがって、TCP/IP処理関数_process_tcpipの周期起動を制御します。

    //関数_process_tcpipの周期起動間隔は、10msec以下に設定します。

    //プロトコル処理部で使用します。

    void tcpudp_act_cyc(unsigned char cycact)

    {

    switch(cycact){

    case 0: //TCP/IP処理関数の周期起動を停止

    tcpip_flag=0;

    break;

    case 1: //CP/IP処理関数の周期起動を開始

    tcpip_flag=1;

    break;

    default:

    tcpip_flag = 0;

    break;

    }

    }

    ///////////////////////////////////////////////////////////////////////

    //tcp_apiから呼び出す

    ///////////////////////////////////////////////////////////////////////

    ///////////////////////////////////////////////////////////////////////

    //T4処理(CPUの10mS割り込みで処理)

    ///////////////////////////////////////////////////////////////////////

    //T4ライブラリのTCP/IP部の処理を行います。

    //本APIからドライバ層へのリードライト関数など、種々ドライバ関数が呼び出されます。

    //本APIの処理時間は通信状態やドライバ層の実装方法によって変化します。

    //本APIのスタックはドライバ層の実装方法によって変化します。

    //本APIはtypeに”1”を指定し、任意の間隔(10msec推奨)で定期的に起動してください。

    //(タイマ割り込みなどを使用)

    extern BOOL ether_enable;

    //WDTの10mS割り込みから

    void t4_interval(void)

    {

    tcpudp_time_cnt++;

    if(ether_enable && tcpip_flag)_process_tcpip(1);

    }

    //EtherCの割り込みから

    void t4_interval_(void)

    {

    if(ether_enable && tcpip_flag)_process_tcpip(1);

    }

    ///////////////////////////////////////////////////////////////////////

    //T4処理(CPUの10mS割り込みで処理) end

    ///////////////////////////////////////////////////////////////////////

    というぐあいで、こんなことになりました、TCPのノンブロッキングサンプルから

    最初にtelnetサーバーでもやってみようかと思います

  • IKUZOさん

    シェルティです、こんにちは。

    コード拝見しました。TCP/IPとEtherドライバが無駄なく結合出来ていると思います。

    これから、アプリを載せていって通信速度やCPU負荷状況が気になってきた場合に、

    Etherドライバに改善の余地有り、と思い返していただけると良いかなと思います。

    アプリ変更せずにEtherドライバとt4_driver.c の改定のみで改善できると思います。


    あと、T4用のアプリですが以下が参考になるかもしれません。

    ワークスペースとしてはRXマイコン用ですがT4のAPIはSH2Aと共通なので

    アプリ部分(DHCP/DNS/FTP/HTTPのコード)の移植は容易と思います。

    RXファミリ 組み込み用TCP/IP M3S-T4-Tinyを使った応用例(DHCP/DNS/FTP/HTTP) Firmware Integration Technology
    R20AN0314JJ0100

    RXマイコンをWebサーバにして、ブラウザからRXマイコンボード上のLEDをコントロール出来るサンプルになってました。

    Webサーバのコンテンツを内蔵ROMに配置するタイプとSDカードかUSBメモリに配置するタイプが用意されています。

    以上です

     

     

     

  • シェルティさん回答ありがとうございます

    2014/9/11 2:21の投稿では画像を添付されてますが、どのようにしたらできますか?

    ご存知であれば、教えていただけませんか?

    RXファミリ 組み込み用TCP/IP M3S-T4-Tinyを使った応用例(DHCP/DNS/FTP/HTTP) Firmware Integration Technologyですがダウンロードしてftpサーバのサンプルところを取り出して

    例のT4のドライバーに接続しまして、ftpからの接続とユザー名、パスワードまでは正常に行くのですが

    ls-lのコマンドで固まります、もうすこしがんばってみます。

  • シェルティさん 画像を添付する方法がわかりました、一度投稿してから編集モードにするとOPTIONタブがでるのでそれを使用して画像を添付できることがわかりました ftpのサンプルのほうですがメモリを参照しているのでそれを全てファイル扱いにしてうまくいくようになりました、_tcp_2msl 変数がTIME-WAIT 1分間でなぜか1分間の間通信が途絶えますが これを50mSぐらいにすると早く通信できます、ファイルのアップロード、ダウンロードができるようになったらまたどのぐらいの速度が出たのか、また報告したいと思います。
  • シェルティさん

    ftpで転送ができるようになりました、FFFTPでの表示では400KByte秒は行くようです、

    これからt4ライブラリを主に使用したいと思います、

    uIPに比べて格段に速度が速いです、いろいろ教えていただきありがとうございました。

    H8/300のライブラリは作成いただけないものでしょうか? CPUを変更してコンパイルするだけと、思いますが、前のリソースも結構ありますので。 よろしくお願いします。
  • IKUZOさん

    こんにちは、シェルティです。

    もうFTPの移植が完了したのですね、素晴らしいです。すごいですね。

    通信速度も400KByte/secと十分実用に適用出来る速度ですね。

    注意としてはT4は送信アルゴリズムが弱いため、ACKが返ってくるのが

    遅い環境だと送信も合わせて遅くなる点です。

    これは近いうちに直すと開発者から聞きましたが現在の最新版(V.2.00)では遅いままですね。

    以下ご質問いただいた内容について回答です。

    ■ご質問①の回答:画像添付の方法

    画像添付については「USE RICH FORMATTING」というリンクを押して

    画像添付のアイコンをクリックしたら出来ました。

    ■ご質問②の回答:TIME_WAIT状態

    以前別のスレッドで別の方から似たご質問が有りまして

    そこで実施した回答が参考になると思います。

    http://japan.renesasrulz.com/cafe_rene/f/69/p/2059/8911.aspx#8911

    ■ご質問③の回答:H8/300のライブラリ

    作ってみます。 T4の最新版はソースコードが付いてて、RXマイコン用のライブラリビルド環境(HEW)も

    付いているので、H8/300用に新規でビルド環境を起こして

    Toolchainの設定を見ながら真似して設定してあげれば出来ると思います。

    が、データの受け渡し方法が良い方法が無い気がしますね。

    もしデータの受け渡し方法が見つからなければ、RXマイコン用のライブラリビルド環境を

    H8/300用に改造する方法を説明したいと思います。

    以上です

  • シェルティ さん

    いつもお世話になっております、以前の投稿記事を拝見しました、_tcp_2mslはできるならそのままで、通信端点をRAMが許す限り多くすれば最大の転送速度になるということで納得しました

    「T4の最新版はソースコードが付いてて」これはまたすばらしい

    時間ができしだい、これもやりたいと思います、

    新規開発ではRXになると思うのですが、H8が残留している基板もありまして

    今回はt4で解決できたので、シェルティ さんに感謝しています。

    ありがとうございました。 

  • IKUZOさん

    こんにちは、シェルティです。

    H8/300でT4ライブラリが作れるか、試してみました。結果OKでした。

    以下手順です。

    ①T4ライブラリの最新版パッケージをダウンロード

    RXファミリ 組み込み用TCP/IP M3S-T4-Tiny: 導入ガイド
    Firmware Integration Technology

    R20AN0051JJ0200

     

    ②T4ライブラリの最新版パッケージの中身のFITモジュールを解凍

    \an_r20an0051jj0200_rx_t4_connectivity\FITModules\r_t4_rx_v2.00.zip

     

    ③FITモジュールの中のビルド環境を解凍

    \r_t4_rx_v2.00\r_t4_rx\make_lib\make_lib.zip

     

    ④\make_lib\T4_Library\hew\T4_Library.hws でHEWを起動する

    ⑤画面左プロジェクトツリーの「T4_Library」で右クリックして、「プロジェクトの挿入」⇒「新規プロジェクト」を選択しOKボタン

    ⑥プロジェクトタイプを「Library」選択しプロジェクト名「T4_Library_h8300h_advance」とし、CPU種別に「H8S, H8/300」を選択

     ツールチェインに「Hitachi H8S, H8/300 Standard」を選択し、OKボタン

    ⑦CPUシリーズに「H8/300H」を選択し「次へ」ボタン ※IKUZOさんのお持ちの環境に合わせてください

    ⑧動作モードに「Advanced」を選択し「完了」ボタン ※IKUZOさんのお持ちの環境に合わせてください

    ⑨以下ソースコードをプロジェクトツリーの「T4_Library_h8300h_advance」にドラッグアンドドロップ

      \make_lib\T4_src

       ether.c, ip.c, T4_Version.c, tcp.c, tcp_api.c, udp.c

    ⑩ビルド→H8S, H8/300 Standard Toolchainのコンパイラタブのオプション項目「インクルードファイルディレクトリ」でインクルードパスを以下追加

      相対パス: Project directory

      サブディレクトリ: ..\..\..\T4_src

    ⑪ビルド→H8S, H8/300 Standard Toolchainのコンパイラタブのオプション項目「マクロ定義」でマクロを以下追加

     _TCP, _UDP, _TCP_DACK, _ETHER, _MULTI, _TEST_LIBRARY, _ICMP, far, _far

    ⑫T4_Version.c にH8/300H用のプリデファインマクロの切り分けが無いので以下を151行目に追加

    #elif defined (__H8__) && defined(__300HA__)
    #define __TARGET_CPU__ "H8/300H Advanced mode"
    #define __COMPILER_VER__ __RENESAS_VERSION__

    ⑬チェックサム演算コードがRXマイコン用にアセンブラ化されていますが、H8/300用のコードは無いので、C言語で書いたコードを登録

     ※次投稿でコードを貼りつけます

     

    これでビルドが通りました。お試しください。

    r_t4_itcpip.h の冒頭にT4の対応マイコン表が書いてありますね。

    ここに書いてある対応マイコンであれば上記と同等の手順でライブラリ生成環境が作れそうです。

    以上です

     

     


  • #include <type.h>

    uint16 _cksum(uchar *data, uint16 nbytes, uint16 sum0)
    {
        uint32 sum;
        uint16 *p_word, word, nwords;

        if (nbytes == 0)
        {
            sum = sum0;
        }
        else
        {
            if (((uint32)data) & 0x1)
            {
                sum0 = ((sum0 >> 8) & 0x00ff) | (sum0 << 8);

                p_word = (uint16 *)(data + 1); /* half word alignment */
                nwords = (nbytes - 1) >> 1;

                for (sum = sum0; nwords > 0; nwords--)
                    sum += *p_word++;

                /* if nbytes odd, add one byte of zero */
                if (nbytes & 0x1)
                {
                    word = 0;
                }
                else
                {
                    /* add last byte */
                    word = net2hs(*p_word);
                    word = word & 0xff00; /* clear lower 8bits */
                }
                /* add first byte */
                p_word = (uint16 *)(data - 1);
                word  |= (net2hs(*p_word) & 0x00ff); /* clear upper 8 bits */
                sum   += hs2net(word);

                sum = (sum >> 16) + (sum & 0xffff); /* add in carry   */
                sum = (sum >> 16) + (sum & 0xffff); /* maybe one more */
                sum = ((sum >> 8) & 0x00ff) | (sum << 8);
            }
            else
            {
                p_word = (uint16 *)data;
                nwords = nbytes >> 1;

                for (sum = sum0; nwords > 0; nwords--)
                    sum += *p_word++;

                /* if nbytes odd, fill zero */
                if (nbytes & 0x1)
                {
                    word = net2hs(*p_word);
                    word = (word >> 8) << 8; /* clear lower 8bits */
                    sum += hs2net(word);
                }
                sum = (sum >> 16) + (sum & 0xffff); /* add in carry   */
                sum = (sum >> 16) + (sum & 0xffff); /* maybe one more */
            }
        }

        sum = ~net2hs(sum);

        return ((uint16)sum);
    }

     

     


     

Reply

  • #include <type.h>

    uint16 _cksum(uchar *data, uint16 nbytes, uint16 sum0)
    {
        uint32 sum;
        uint16 *p_word, word, nwords;

        if (nbytes == 0)
        {
            sum = sum0;
        }
        else
        {
            if (((uint32)data) & 0x1)
            {
                sum0 = ((sum0 >> 8) & 0x00ff) | (sum0 << 8);

                p_word = (uint16 *)(data + 1); /* half word alignment */
                nwords = (nbytes - 1) >> 1;

                for (sum = sum0; nwords > 0; nwords--)
                    sum += *p_word++;

                /* if nbytes odd, add one byte of zero */
                if (nbytes & 0x1)
                {
                    word = 0;
                }
                else
                {
                    /* add last byte */
                    word = net2hs(*p_word);
                    word = word & 0xff00; /* clear lower 8bits */
                }
                /* add first byte */
                p_word = (uint16 *)(data - 1);
                word  |= (net2hs(*p_word) & 0x00ff); /* clear upper 8 bits */
                sum   += hs2net(word);

                sum = (sum >> 16) + (sum & 0xffff); /* add in carry   */
                sum = (sum >> 16) + (sum & 0xffff); /* maybe one more */
                sum = ((sum >> 8) & 0x00ff) | (sum << 8);
            }
            else
            {
                p_word = (uint16 *)data;
                nwords = nbytes >> 1;

                for (sum = sum0; nwords > 0; nwords--)
                    sum += *p_word++;

                /* if nbytes odd, fill zero */
                if (nbytes & 0x1)
                {
                    word = net2hs(*p_word);
                    word = (word >> 8) << 8; /* clear lower 8bits */
                    sum += hs2net(word);
                }
                sum = (sum >> 16) + (sum & 0xffff); /* add in carry   */
                sum = (sum >> 16) + (sum & 0xffff); /* maybe one more */
            }
        }

        sum = ~net2hs(sum);

        return ((uint16)sum);
    }

     

     


     

Children
  • シェルティ さんお世話になっております 早速ダウンロードしてビルドして見ました、エラーなくビルドできました H8ネットワーク関連でもおかげでT4全てとなりそうです LANインターフェースICはリアルテック製ですが、ドライバ層と完全に分離しているので導入は短期間で完了しそうです、できましたら早めに、結果等、 報告できたらと思っています いつもご親切な回答をありがとうございます よろしくお願いいたします。
  • いつもお世話になっています。

    M3S-T4-Tiny でtelnetのサンプルなどはご存じないでしょうか?

  • IKUZOさん

    こんにちは、シェルティです。

    telnetサンプルはないと思います。

    telnetサーバ側でしょうか? クライアント側でしょうか?
    いずれもT4ライブラリのAPI(サーバ⇒tcp_acp_cep()、クライアント⇒tcp_con_cep())を
    使えばユーザアプリで実装できると思います。

    サンプルで付属しているエコーサーバの待ち受けポートを23番に変更して、
    tcp_rcv_dat()で受信したデータをtcp_snd_dat()でオウム返ししているところを、
    受信データ解析して受信データに応じて処理してレスポンスをtcp_snd_dat()で送ることで
    telnetサーバ的な動作を実現することはできると思います。

    以上です

  • シェルティさん

    いつもありがとうございます、

    「tcp_snd_dat()でオウム返ししているところを、受信データ解析して受信データに応じて処理」ということでやってみます。

    R20AN0314JJ0100サンプルでhttpもやりたいのですがhttpとDNSが関係しているのですがhttpのみ取り出して

    もうしわけありませんマニュアルを読む前ですが、

    R_httpd();とhttp_callbackだけを手当てしてやればよいのでしょうか?DNSも含めないといけないのでしょうか?

    FTPの場合はR_ftp_srv_open();があったのですが、httpは無いようなので。

    FTPは調子が良いです。

  • R_httpd();とhttp_callbackを手当てしてやってみると、

    void R_httpd(void)でcase HTTPD_CLOSED:の

    if(ercd != E_WBLK){でwhile (1);にはまります

    なにが足りないのかな?

    そこだけ違うCPUに抜き出してやっているので

    マニュアル等は詳しいものはありませんでした。

  • もしかしたら、リアルタイムOS用のブロッキングコール用のソース?

    ちょっと調べてみます

  • とりあえず、while (1);をreturn;にしてやりました、


  • IKUZOさん

    こんにちは、シェルティです。

    下記回答します。

    > R_httpd();とhttp_callbackだけを手当てしてやればよいのでしょうか?DNSも含めないといけないのでしょうか?

    手当はもう少し必要です。DNSは不要です。

    手当①:config_tcpudp.c の手当て
    config_tcpudp.c のTCP通信端点設定(tcp_ccep構造体)とTCP受付口(tcp_crep構造体)を見直しましょう。
    R20AN0314JJ0100のサンプルはRXマイコンの各種ボード用にWebサーバ、FTPサーバ、
    DNSクライアント、DHCPクライアントを実装したものですね。
    https://www.renesas.com/ja-jp/software/D6000403.html
    ⇒RX65Nの発売に合わせて更新されたようです。

    上記サンプルだと以下のようになっています。
    それぞれ1行1IDとなります。

    通信端点IDは各APIの第1引数に、受付口IDはtcp_acp_cep()の第2引数に指定します。
    通信端点IDはシステム上複数動作しているアプリを識別するための番号、
    受付口IDはtcp_acp_cep()で待ち受けるポート番号を識別するための番号ですね。
    ゼロになっているところは未実装の設定フィールドです。
    例外として通信端点の1個目のメンバーでEtherのチャネル番号を指定できるようです。

    たとえば、下記設定のシステムでtcp_acp_cep(5, 5, ...); と指定すると、21番ポートで待ち受けて、
    接続が完了するとftp_callback()が呼び出される、という寸法ですね。

    T_TCP_CREP tcp_crep[] =
    {
        { 0x0000, { 0, 21 }}, /* 受付口ID=1 */
        { 0x0000, { 0, 20 }}, /* 受付口ID=2 */
        { 0x0000, { 0, 21 }}, /* 受付口ID=3 */
        { 0x0000, { 0, 20 }}, /* 受付口ID=4 */
        { 0x0000, { 0, 21 }}, /* 受付口ID=5 */
        { 0x0000, { 0, 20 }}, /* 受付口ID=6 */
     { 0x0000, { 0, 80 }}, /* 受付口ID=7 */
     { 0x0000, { 0, 80 }}, /* 受付口ID=8 */
     { 0x0000, { 0, 80 }}, /* 受付口ID=9 */
     { 0x0000, { 0, 80 }}, /* 受付口ID=10 */
    }

    T_TCP_CCEP tcp_ccep[] =
    {
     { 0, 0, 0, 0, 128, ftp_callback },   /* 通信端点ID=1 */
     { 0, 0, 0, 0, 1460, ftp_data_callback }, /* 通信端点ID=2 */
     { 0, 0, 0, 0, 128, ftp_callback },   /* 通信端点ID=3 */
     { 0, 0, 0, 0, 1460, ftp_data_callback }, /* 通信端点ID=4 */
     { 0, 0, 0, 0, 128, ftp_callback },   /* 通信端点ID=5 */
     { 0, 0, 0, 0, 1460, ftp_data_callback }, /* 通信端点ID=6 */
     { 0, 0, 0, 0, 1460, http_callback },  /* 通信端点ID=7 */
     { 0, 0, 0, 0, 1460, http_callback },  /* 通信端点ID=8 */
     { 0, 0, 0, 0, 1460, http_callback },  /* 通信端点ID=9 */
     { 0, 0, 0, 0, 1460, http_callback },  /* 通信端点ID=10 */
    }

    手当②:FTPサーバとWebサーバのコンフィグの手当て
    次にFTPサーバとWebサーバのコンフィグの手当てをします。
    コンフィグファイルは、r_t4_http_server_rx_config.h、r_t4_ftp_server_rx_config.hです。
    それぞれHTTP_START_TCP_CEP、FTP_START_TCP_CEPというのがあります。
    デフォルトだとどちらも"0"になっています。
    HTTP_START_TCP_CEPを6、FTP_START_TCP_CEPを0とすると良いでしょう。
    (通信端点は1からスタートなのに、FTPサーバとWebサーバの設定は0からスタート、混乱してしまいます)

    > if(ercd != E_WBLK){でwhile (1);にはまりますなにが足りないのかな?

    おそらくですが、FTPサーバとWebサーバとで同じ通信端点に対しtcp_acp_cep()を発行してしまい、
    E_QOVRが戻ってきているものと思われます。上記調整で解消するのではないでしょうか。

    > もしかしたら、リアルタイムOS用のブロッキングコール用のソース?

    これは今のところ関係ないと思います。

    > とりあえず、while (1);をreturn;にしてやりました、

    この対処だとウェブサーバは動作しないと思います。

    以上です

  • シェルティさん

    いつもありがとうございます、

    助かりました、以下のように

    const T_TCP_CCEP tcp_ccep[] =

    {

    //1.属性 ,

    //2.送信ウィンドウの先頭アドレス,

    //3.送信ウィンドウのサイズ,

    //4.受信ウィンドウの先頭アドレス,

    //5.受信ウィンドウのサイズ,

    //6.コールバックルーチンアドレス(関数名)

    //  コールバック機能を使用しない場合には、NULL(=0)を設定

    { 0, 0, 0, 0, 128, ftp_callback },//ID=1 ->FTP_START_TCP_CEP 0

    { 0, 0, 0, 0, 1460, ftp_data_callback },//ID=2

    { 0, 0, 0, 0, 128, ftp_callback },//ID=3

    { 0, 0, 0, 0, 1460, ftp_data_callback },//ID=4

    { 0, 0, 0, 0, 128, ftp_callback },//ID=5

    { 0, 0, 0, 0, 1460, ftp_data_callback },//ID=6

    { 0, 0, 0, 0, 1460, http_callback },//ID=7 ->HTTP_START_TCP_CEP 6

    { 0, 0, 0, 0, 1460, http_callback },//ID=8

    { 0, 0, 0, 0, 1460, http_callback },//ID=9

    { 0, 0, 0, 0, 1460, http_callback },//ID=10

    { 0, 0, 0, 0, 128, t4_callback },//ID=11 ->TELNET_START_TCP_CEP 10

    { 0, 0, 0, 0, 128, t4_callback },//ID=12

    { 0, 0, 0, 0, 128, t4_callback },//ID=13

    };

    このようにしましたら、FTP、HTTP、TELNETで支障なくcallback を呼び出すことができました

    引き続きやってみます。

  • お世話になります

    t4_callback内のTFN_TCP_ACP_CEP:は確立済みと思いまして、tcp_snd_dat(cepid,をやってtelnetターミナル画面には文字が表示されます、その後case TFN_TCP_SND_DAT:からlen=(int)tcp_rcv_dat(を実行しますと、E_QOVR 、E_WBLK、E_WBLK等で受信に失敗します、アドバイスいただけませんか?