RX65Nでプログラムが大きくなるとイーサネットが動作しくなる

開発環境:e2 studio (Version: 2023-01 (23.1.0))
Toolchains:GCC for Renesas RX - 8.3.0.202204

FITDemosのrskrx65n_2mb_udp_nonblockingを参考にUDPのエコーサーバーを作成しました。
r_t4_rxのDHCPはEnableに設定しており、正常にIPが割り当てられエコーサーバーも正常に動作していました。

このアプリに.h、.cファイルを追加していき、プログラムが大きくなってくると、ある時からイーサネットの機能が動かなくなりました。
具体的にはDHCPのDiscoveryが送信されなくなりました。
この時イーサネットの開始に必要な以下の処理は成功しています。
lan_open() →成功
tcpudp_get_ramsize() →バッファサイズ正常
tcpudp_open() →成功
また、メインループは正常に動いていている(LED点滅)ことを確認しています。
(.h、.cを削除して処理を削ると、また正常に動作するようになります)

イーサネットが機能しなくなる件について、情報をお持ちであったり、心当たりがある方がいらっしゃいましたら教えていただけると幸いです。
よろしくお願いします。

  • 追記:CC-RXで同じプロジェクトを作成すると問題なく動作する

  • キャンディさん、こんにちは。NoMaYと申します。

    ちょっと確認させて欲しいのですが、単にファイルを追加しただけで動かなくなったわけでは無いのですよね?つまり、追加したファイルの中のコードは何かしら実行されているのですよね?それとも、それこそ単純にファイルを追加していっただけで、動かなくなってしまうのでしょうか?

    > このアプリに.h、.cファイルを追加していき、プログラムが大きくなってくると、ある時からイーサネットの機能が動かなくなりました。
    > (.h、.cを削除して処理を削ると、また正常に動作するようになります)

    > 追記:CC-RXで同じプロジェクトを作成すると問題なく動作する


    それでも、ひとまず、コンパイラの最適化の観点から試してみることとして、以下のことがあります。(最適化の名称は厳密では無くて、ちょっと疎覚えですけれども。) なお、どれもプログラムの規模の件とは関係が無いのですけれども、CC-RXで動いていたプログラムがGCC for Renesas RXで動かない、という現象に着眼しますと、まずこのあたりから試し始めると思うのです。

    (1) 最適化オプションを -O0、-O2、-O3、-Og、ぐらいで幾つか変えて試してみる(下げてみたり上げてみたりです)
    (2) 分岐最適化(-mrelax)を指定してたら解除してみる
    (3) リンク時最適化(-lto)を指定していたら解除してみる

    あと、ちょっと発想を変えて、以下を試してみることも考えられます。

    (A) CC-RX側で最適化オプションを -optimize=max にしてみる(そうしたらCC-RXでも動かなくなった、という可能性もあります)


  • NoMaYさん、返信ありがとうございます。

    >ちょっと確認させて欲しいのですが、単にファイルを追加しただけで動かなくなったわけでは無いのですよね?
    >つまり、追加したファイルの中のコードは何かしら実行されているのですよね?
    >それとも、それこそ単純にファイルを追加していっただけで、動かなくなってしまうのでしょうか?
    ファイルを追加しただけでファイル内のコードは実行していません。(関数をコールしていない)

    >(1) 最適化オプションを -O0、-O2、-O3、-Og、ぐらいで幾つか変えて試してみる(下げてみたり上げてみたりです)
    効果はありませんでした。

    以下について試してみようと思います。
    検証結果はまた、報告させていただきます。
    >(2) 分岐最適化(-mrelax)を指定してたら解除してみる
    >(3) リンク時最適化(-lto)を指定していたら解除してみる

  • キャンディさん、こんにちは。NoMaYです。

    > ファイルを追加しただけでファイル内のコードは実行していません。(関数をコールしていない)

    そうだったのでしたか。そういうことですと、たぶん私は次に以下のようなことを試すと思うのです。ただ、それで何か手掛かりが掴めるかどうかというと、私自身が試してみる場合も、何とも分からないことですけれども。(また、試している途中で何かに気付いて作戦を変えることもありそうですけれども。)

    (4) リンク順やリンカスクリプトを弄って、追加したファイルのROM/RAMが、それまで動いていたコードの後ろに追加されるだけになるようにする
    (4') たぶん、dataセクションをどう弄るか、というのがややこしそうです

    もっとも、言うは易し、行うは難し、という感じで、そう試してみるだけでも私自身でも頭を抱えそうですけれども。


    あと、手続き的な考え方の他に、RXマイコンのイーサネット周りでROM/RAMの配置にクセがある点として、イーサネット向けDMAバッファだかが16バイトアラインメントされていないといけない、というのがあったと思いますので、その点も気になるところです。

  • キャンディさんこんにちは。

    以前に実装して、長らく使っていなかった、RX71M の Ethernet 自前のアプリを自分も試してみました。(T4ライブラリ利用)

    Toolchain: rx-elf-gcc.exe (GCC_Build_20200327) 8.3.0.202002-GNURX 20190222

    アプリはHTTPサーバーで、前は動作していたと思うのですが、DHCP の取得でタイムアウトします。

    アプリは、DHCP がタイムアウトすると、指定の IP アドレス(192.168.0.20)を設定するような実装になっています。

    ping は loss=0 で通るのですが、HTTPサーバーは動作していません。

    テストしたソースはかなり古く、周辺のコードが改修された為、その影響によるのかもしれません。(現在調査中)

    もう少し調べてみますが、DHCP が取得出来ない不具合が同じなのが気になります・・、何か進展がありましたら、自分もポストします。

    http://www.rvf-rc45.net/wordpress/?p=3023

    ※上記ブログ記事は、gcc-6.4.0 を自分でビルドして利用していた頃のものです。

    ---

    自分は、ドライバーのソースを修正して、EDMAC(イーサーネット専用DMAC)のメモリアドレスが32バイト境界になるようにしています。

    元ソースは、EDMAC が使う構造体に専用のセクションを割り当てて、必ず32バイト境界になるような実装だったと思います。

  • NoMaYさん、ありがとうございます。

    .mapの比較はしたのですが、特におかしな点は無いようでした。
    (見つけられないだけかもしれませんが…)

    DMAバッファの件は私の知識ではどうアプローチしたらよいのかよくわかりませんが…
    時間の取れる時に継続調査したいと思います。

  • hirakuni45さん、調査までしていただいてありがとうございます。

    NoMaYさんも仰っていたDMA周りに何かあるのかもしれませんね。
    (この辺りはよくわかっていないのですが…)
    時間の取れる時に継続調査したいと思います。

  • キャンディさん

    こんにちは、シェルティです。ルネサスの中の人です。件のT4ライブラリの設計者です。

    NoMaYさんやhirakuni45さんにご指摘いただいている、EDMAC関連のデータ置き場のアライメントが気になりますね。実はGCC版だとスマートコンフィグレータでこのあたりのアライメントが調整できず、ユーザが自力でリンカスクリプトを調整する必要があります。

    キャンディさんが作られた直後はたまたまアライメントが取れてて、コード追加するにつれてアライメントが取れなくなり動かなくなったのでは、と思います。

    以下、シェルティがプロジェクト新規作成してみたところですが、B_ETHERNET_BUFFERS_1(32バイトアライメントが必要)とB_TX_DESC_1とB_RX_DESC_1(16バイトアライメントが必要)がアライメントが取れていない位置に配置されています。

    アライメントの調整についてはEtherドライバの資料に記載がありますのでご参照ください。

    https://github.com/renesas/rx-driver-package/blob/master/source/r_ether_rx/r_ether_rx_vx.xx/r_ether_rx/doc/ja/r01an2009jj0123-rx-ether.pdf

    ⇒5.1.1 GCC for Renesas RX のセクション設定例

    以上です

  • シェルティさん、ありがとうございます。
    明日にでも試してみて結果報告します。

  • こんにちは、みなさん~

    進展がありましたので報告します。

    ---

    まず、DHCP が取れないのは、自分のフレームワークを色々更新する過程で、Ethernet のポート設定を間違っていた為で、それに気がつき、修正した処、DHCP の取得は出来るようになりました。

    それで、DHCP で取得した IP 192.168.0.10 に対して、ping のテストをしても、タイムアウトで通信出来ません。

    次に、GNU-RX のツールを、自前でビルドした、gcc-6.4.0 に戻して、フルコンパイルしました。

    すると、今度は、通信出来るようになり、HTTP サーバーへの接続も可能になりました。

    非常に不思議な現象で、GNU-RX gcc-8.3.0 でコンパイルすると通信出来ず、gcc-6.4.0 ならちゃんと動作します。

    binutils-2.30, gcc-6.4.0, newlib-2.4.0 ---> OK

    binutils-2.34, gcc-7.5.0, newlib-2.4.0 ---> OK

    上記の組み合わせで動作を確認しています。

    この現象は、前に経験があり、その時は、以下の組み合わせで NG でした。

    binutils-2.30, gcc-6.4.0, newlib-3.0.0 ---> NG

    GNU-RX 8.3.0 は以下の組み合わせのようです。
    • binutils-2.24
    • gcc-8.3.0
    • newlib-3.1.0

    何故動作しなくなるのか、詳しく調べていませんが、現状、そのような状態です。

    ---

    引き続き調査をします。