RX SmartConfigurator FIT e2studioプロジェクトをMinGWでbuildしてみる(もちろん実行出来ませんけれど)

こんにちは。NoMaYです。

別スレッド「RXシュミレータでの最小プログラムの作成について」でRXシミュレータの代わりにMinGWを使うと言う話が出ていましたので、とりあえず、ビルド出来るようにするにはどうすれば良いのだろうか試してみることにしました。

まずはMingGWのインストールから。今回、以下を参考にさせて頂きました。私は64bit版をインストールしてみました。[追記] 正確には、MinGW-W64にて、64bitターゲットアーキテクチャを選択したのですが、この選択は不適切でしたので、後日、32bitターゲットアーキテクチャを選択し直しました。

gccのインストール(Windows) - 電気通信大学
joho.g-edu.uec.ac.jp/joho/gcc_win/





続く。

  • こんにちは。NoMaYです。

    FITのBSPモジュールのソースの1つにr_rx_compiler.hというヘッダファイルがあるのですが、そのファイルに細工をして以下の画面コピーのレベルまでエラーやワーニングを減らしました。(あと、FreeRTOSポートレイヤのportmacro.hというヘッダファイルもですが、余り重要ではないです。) ここまで減らせば、まあ後は何とかなるだろう、というレベルかなと思います。細工の内容は、以下の画面コピーの後に書いてあります。次の作業では、流用元プロジェクトをGNURX版からCC-RX版へ戻します。

    続く。

    画面コピー






    細工の内容 (赤文字部分が追加箇所)

    r_rx_compiler.h

    /* ---------- Interrupt Function Creation ---------- */
    #if defined(__CCRX__)



    #elif defined(__GNUC__) && !defined(__WINNT__)

    /* Standard */
    #define R_BSP_PRAGMA_INTERRUPT(function_name, vector)                 extern void function_name(void) __attribute__((interrupt(R_BSP_SECNAME_INTVECTTBL, vector)));
    #define R_BSP_PRAGMA_STATIC_INTERRUPT(function_name, vector)          static void function_name(void) __attribute__((interrupt(R_BSP_SECNAME_INTVECTTBL, vector), used));

    #define R_BSP_PRAGMA_INTERRUPT_FUNCTION(function_name)                extern void function_name(void) __attribute__((interrupt));
    #define R_BSP_PRAGMA_STATIC_INTERRUPT_FUNCTION(function_name)         static void function_name(void) __attribute__((interrupt, used));

    #define R_BSP_ATTRIB_INTERRUPT                                        extern /* only this one because __attribute__((interrupt)) prevents GNURX from generating vector */
    #define R_BSP_ATTRIB_STATIC_INTERRUPT                                 static /* only this one because __attribute__((interrupt, used)) prevents GNURX from generating vector */

    /* Fast */
    #define R_BSP_PRAGMA_FAST_INTERRUPT(function_name, vector)            extern void function_name(void) __attribute__((interrupt(R_BSP_SECNAME_INTVECTTBL, vector))) \
                                                                                                          __attribute__((fast_interrupt));
    #define R_BSP_PRAGMA_STATIC_FAST_INTERRUPT(function_name, vector)     static void function_name(void) __attribute__((interrupt(R_BSP_SECNAME_INTVECTTBL, vector), used)) \
                                                                                                          __attribute__((fast_interrupt, used));

    #define R_BSP_PRAGMA_FAST_INTERRUPT_FUNCTION(function_name)           extern void function_name(void) __attribute__((fast_interrupt));
    #define R_BSP_PRAGMA_STATIC_FAST_INTERRUPT_FUNCTION(function_name)    static void function_name(void) __attribute__((fast_interrupt, used));

    #define R_BSP_ATTRIB_FAST_INTERRUPT                                   extern /* __attribute__((interrupt(fast))) Not necessary,
                                                                                    but Don't forget a R_BSP_PRAGMA_FAST_INTERRUPT() declaration */
    #define R_BSP_ATTRIB_STATIC_FAST_INTERRUPT                            static /* __attribute__((interrupt(fast)), used) Not necessary,
                                                                                    but Don't forget a R_BSP_PRAGMA_STATIC_FAST_INTERRUPT() declaration */

    /* Default */
    #define R_BSP_PRAGMA_INTERRUPT_DEFAULT(function_name)                 extern void function_name(void) __attribute__((interrupt(R_BSP_SECNAME_INTVECTTBL, "$default")));
    #define R_BSP_PRAGMA_STATIC_INTERRUPT_DEFAULT(function_name)          static void function_name(void) __attribute__((interrupt(R_BSP_SECNAME_INTVECTTBL, "$default"), used));

    #elif defined(__ICCRX__)



    #elif defined(__GNUC__) && defined(__WINNT__)

    /* Standard */
    #define R_BSP_PRAGMA_INTERRUPT(function_name, vector)                 extern void function_name(void);
    #define R_BSP_PRAGMA_STATIC_INTERRUPT(function_name, vector)          static void function_name(void) __attribute__((used));

    #define R_BSP_PRAGMA_INTERRUPT_FUNCTION(function_name)                extern void function_name(void);
    #define R_BSP_PRAGMA_STATIC_INTERRUPT_FUNCTION(function_name)         static void function_name(void) __attribute__((used));

    #define R_BSP_ATTRIB_INTERRUPT                                        extern
    #define R_BSP_ATTRIB_STATIC_INTERRUPT                                 static

    /* Fast */
    #define R_BSP_PRAGMA_FAST_INTERRUPT(function_name, vector)            extern void function_name(void);
    #define R_BSP_PRAGMA_STATIC_FAST_INTERRUPT(function_name, vector)     static void function_name(void) __attribute__((used));

    #define R_BSP_PRAGMA_FAST_INTERRUPT_FUNCTION(function_name)           extern void function_name(void);
    #define R_BSP_PRAGMA_STATIC_FAST_INTERRUPT_FUNCTION(function_name)    static void function_name(void) __attribute__((used));

    #define R_BSP_ATTRIB_FAST_INTERRUPT                                   extern
    #define R_BSP_ATTRIB_STATIC_FAST_INTERRUPT                            static

    /* Default */
    #define R_BSP_PRAGMA_INTERRUPT_DEFAULT(function_name)                 extern void function_name(void);
    #define R_BSP_PRAGMA_STATIC_INTERRUPT_DEFAULT(function_name)          static void function_name(void) __attribute__((used));

    #endif

     

    /* ---------- Inline Expansion of Assembly-Language Function (part2) ---------- */
    #if defined(__CDT_PARSER__)



    #else

    #if defined(__CCRX__)



    #elif defined(__GNUC__) && !defined(__WINNT__)

    #define _R_BSP_ASM(...)           #__VA_ARGS__
    #define R_BSP_ASM(...)            _R_BSP_ASM(__VA_ARGS__\n)
    #define R_BSP_ASM_LAB_NEXT(n)     ?+
    #define R_BSP_ASM_LAB_PREV(n)     ?-
    #define R_BSP_ASM_LAB(n_colon)    R_BSP_ASM(?:)
    #define R_BSP_ASM_BEGIN           __asm__ volatile (
    #define R_BSP_ASM_END             R_BSP_ASM(rts));

    #elif defined(__ICCRX__)



    #elif defined(__GNUC__) && defined(__WINNT__)

    #define _R_BSP_ASM(...)
    #define R_BSP_ASM(...)
    #define R_BSP_ASM_LAB_NEXT(n)
    #define R_BSP_ASM_LAB_PREV(n)
    #define R_BSP_ASM_LAB(n_colon)
    #define R_BSP_ASM_BEGIN
    #define R_BSP_ASM_END

    #define __asm( ... )
    #define asm( ... )

    #endif

    #endif /* defined(__CDT_PARSER__) */


    portmacro.h

    #if !defined(__WINNT__)
        #define _portASM( ... )              __asm volatile ( #__VA_ARGS__ "\n" );
        #define portASM( ... )               _portASM( __VA_ARGS__ )
        #define portASM_LAB_NEXT( name )     ?+
        #define portASM_LAB_PREV( name )     ?-
        #define portASM_LAB( name_colon )    _portASM( ?: )
        #define portASM_BEGIN
        #define portASM_END
    #elif defined(__WINNT__)
        #define _portASM( ... )
        #define portASM( ... )
        #define portASM_LAB_NEXT( name )
        #define portASM_LAB_PREV( name )
        #define portASM_LAB( name_colon )
        #define portASM_BEGIN
        #define portASM_END
        #define volatile( ... ) ( "" )
    #endif

     

  • NoMaYさん

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

    ありがとうございます。BSPの開発チームに検討依頼出しました。いつも開発にご協力いただき感謝です。

    以上です

  • NoMaYさん、こんにちは。

    自分もlongのサイズは意識していませんでした(汗)

    ビルドができるようになれば、全体を実行することはできなくても
    CUnit(C++ならGoogleTestでも)での単体テストならできそうですね。

    CGの場合は以下のような細工になります。
    (自分はデバッグしやすいようにもうちょっと細工していますが)

    iodefine.h
    #define DI() asm("di") // ここは変更なし
    ...(略)...

    #if !defined(__WINNT__) // 実機用、従来の定義
    #define P0 (*(volatile union un_p0 *)0xFFF00).p0
    #define P0_bit (*(volatile union un_p0 *)0xFFF00).BIT
    #define P1 (*(volatile union un_p1 *)0xFFF01).p1
    #define P1_bit (*(volatile union un_p1 *)0xFFF01).BIT
    ...(略)...
    #else                               // MinGW用
    extern unsigned char sfr_buf[256];
    #define P0 (*(volatile union un_p0 *)(sfr_buf + 0x00000)).p0
    #define P0_bit (*(volatile union un_p0 *)(sfr_buf + 0x00000)).BIT
    #define P1 (*(volatile union un_p1 *)(sfr_buf + 0x00001)).p1
    #define P1_bit (*(volatile union un_p1 *)(sfr_buf + 0x00001)).BIT
    ...(略)...
    #endif

    適当な.cをつくって
    unsigned char sfr_buf[256];

    void asm(char *code) // gcc -fno-asm
    {
        if (strcmp(code, "di") == 0)
        {
            ...(略)...

  • こんにちは。NoMaYです。

    前の投稿では流用元プロジェクトをGNURX版にしていましたが、それをCC-RX版に戻しました。また、前回よりも少し念を入れてリンク出来るところまでやってみました。BSPモジュール(+r_cg_macrodriver.h)の変更箇所は以下の画面コピーの通り(全部では無くて少し省略しています)ですが、変更ファイルは以下のzipファイルに固めました。(なお、MinGW用のプロジェクトファイルとFreeRTOSポートレイヤ側は入れませんでした。また、条件コンパイルの切り方は試行錯誤中です。)

    rx_fit_e2studio_mingw_20210626.zip

    ここまで来ると以下のようなことも試してみたいです。

    (1) FreeRTOSのWindows版(MinGW版)をe2 studioにインポートして試す
    (2) emWinのWindows版(MinGW版)をe2 studioにインポートして試す
    (3) 今回のものと上記の2つを組み合わせてみる
    (4) 上記に対向ベンチも付けて動かしてみる
    (5) ワーニングレベルを上げてみる
    (6) Visual C/C++では?(FreeRTOSとemWinのVisual C/C++版はある)
    (6') clangでは?(FreeRTOSとemWinのclang版は無いような?)

    [追記]

    (A) FreeRTOS with AWS IoT libraries (Amazon FreeRTOS)もWindows版があったような

    [ここまで]

    以下、画面コピーです。

    MingGWでのマクロ定義


    MingGWでのビルド


    変更ファイル


    変更箇所(全部では無くて少し省略しています)













    途中省略


     

  • こんにちは。NoMaYです。

    > (A) FreeRTOS with AWS IoT libraries (Amazon FreeRTOS)もWindows版があったような

    ああ、だから、RXでも、FITのTCP/IPモジュールベースではインターネット通信のシミュレーションは出来ないけれども、FreeRTOSのTCP/IPモジュールベースであればインターネット通信のシミュレーションが出来る、わけだよね、、、そして、FITの他のモジュールとFreeRTOSのTPC/IPモジュールは混在可能である、と。(なぜなら、RX実機版Amazon FreeRTOSで混在出来ているのだから。)

  • こんにちは。NoMaYです。

    > FreeRTOSのTCP/IPモジュールベースであればインターネット通信のシミュレーションが出来る、わけだよね、、、

    試す時は、そうだ、私には、いきなりクラウドに繋ぐのは荷が重いので、まず、かふぇルネのRSSを読むところから初めてみよう、、、

  • こんにちは。NoMaYです。

    > かふぇルネのRSSを読むところから初めてみよう、、、

    そして、読み出した内容をPC上のemWinシミュレータ上に表示して、ページアップ/ページダウンのタッチボタンを模した部分をマウスでクリックして表示をページアップ/ページダウンさせてみるとか、、、

    ミソは、どういう風に「実機でもシミュレータでも同じソースが動いていますよ感」を醸し出すか、でしょうかね、、、あと、いかにも「簡単にビルドを切り替えられますよ」っぽく見せるにはどうするか、でしょうかね、、、

  • こんにちは。NoMaYです。

    そういえば、以前に以下のスレッドがあったのですが、VSCode上でのエディタの無用なワーニングが表示されないようにすることと、Visual C/C++でビルドだけでも出来るようにすることとは、結局、ほとんど等価なこと、になりますかね。(それが、エディットはVSCode、ビルドはe2 studio+MinGW、という形になるとしても。)

    VSCode上での#pragma packエラーを黙らせる良い方法は?
    japan.renesasrulz.com/cafe_rene/f/forum21/6615/vscode-pragma-pack

    [追記]

    > エディットはVSCode、ビルドはe2 studio+MinGW、

    実機向けでは、エディットはVSCode、ビルドはe2 studio+CC-RX/GNURX/ICCRX、(私特有としてデバッグはCS+)、とか、、、

  • NoMaYさん、こんにちは。

    TCP/IP程度なら、FreeRTOSのWindows版で、実行までできる
    周辺機能を使って、例えばCANやSPI,I2Cの通信をしたいとなるとちょっと難しい
    というところでしょうか。

    空実装で素通りするだけで、一応そのまま動くということならよいのですが
    送信完了フラグが立つまで無限ループする処理になっていて
    そこをコメントアウトしないとWindowsでは動かない
    というようなアプリケーションだと苦しいですね。
    (FITならそういうプログラムにはならないのでしょうか)

    それでも画面の表示やキー(タッチ)操作まで再現できるのなら、かなり面白いと思います。
    あとは、e2 studioを2個立ちあげて、シミュレータ同士で通信させるとか。
    個人的には、対向からコマンドを入れて応答があれば、動いてるなと感じます。

  • NoMaYさん

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

    本件引き続きBSPに反映できないか検討を進めてます。

    実機ベースのシミュレーションができるまでになれば最高なのですがなかなかそこまでの道のりは長く、それでも一般的な静的解析ツール(FacebookのInfer等)に掛けるようなユースケースや、コード自体の単体テストを実機を使わず実行するといったユースケースにはすぐリーチできると考えており、BSPへの適用行数もそれほど多くないので適用したいとシェルティとしては考えてます。

    またFreeRTOSの内部動作解析ですが、(有料ツールですが)Tracealyzerというツールが大変良いです。割り込みが入ってから何ns後に○○のキューでデータを送信して△△タスクが起床する・・・等が手に取るようにわかります。

    https://percepio.com/tz/freertostrace/

    以上です