CC-RXもGNURXもC99仕様では_Pragmaプリプロセッサ演算子というものが使えるのですね(FITのコンパイラ対応の効率化に役立ちそうかも)

こんにちは。NoMaYです。

別スレッド『Amazon FreeRTOSだそうです。ルネサスさんのRXは参加しないのかな?』でCC-RX用プロジェクトをGNURX用プロジェクトへ移植する作業をぽつりぽつりとやっていて、CC-RXの#pragma pack / #pragma packoption相当のものとしてGNURXで#pragma pack(1) / #pragma pack()が使えることに気付いたのですが、たまたま同じタイミングで更に別スレッドの作業をやっていてGNURXで#pragma address 変数名 アドレスという記述が使えるらしいことに気付き、調べているうちにFITが前提としているC99仕様では_Pragmaプリプロセッサ演算子(関連リンク参照)というものが使えることを知りました。_Pragmaを使うと以下のように#pragmaをプリプロセッサで扱うことが出来るようになり、FITのコンパイラ対応の効率化に役立ちそうかも知れないと思いました。

#define R_PRAGMA(...) _Pragma(#__VA_ARGS__)

#if defined(__CCRX__)

#define R_PRAGMA_PACK       R_PRAGMA(pack)
#define R_PRAGMA_PACKOPTION R_PRAGMA(packoption)

#elif defined(__GNUC__)

#define R_PRAGMA_PACK       R_PRAGMA(pack(1))
#define R_PRAGMA_PACKOPTION R_PRAGMA(pack())

#endif
/*
 * EDMAC descriptor as defined in the hardware manual. It is
 * modified to support little endian CPU mode.
 */
    R_PRAGMA_PACK

typedef struct DescriptorS
{
    __evenaccess uint32_t           status;
    #if __LIT
    /* Little endian */
    __evenaccess uint16_t           size;
    __evenaccess uint16_t           bufsize;
    #else
    /* Big endian */
    __evenaccess uint16_t bufsize;
    __evenaccess uint16_t size;

    #endif
    uint8_t            *buf_p;
    struct DescriptorS *next;
} descriptor_t;

/*
 * Ethernet buffer type definition.  
 */
typedef struct EtherBufferS
{
    uint8_t buffer[EMAC_NUM_BUFFERS][ETHER_CFG_BUFSIZE];

} etherbuffer_t;

typedef struct pause_resolutionS
{
    pausemask_t mask;
    pauseval_t  value;
    uint8_t     transmit;
    uint8_t     receive;
} pauseresolution_t;

typedef struct
{
    volatile struct st_etherc __evenaccess * petherc; /* ETHERC module */
    volatile struct st_edmac __evenaccess * pedmac; /* EDMAC */
    volatile uint32_t         __evenaccess * preg_pir;
    uint32_t                  phy_address;
    uint8_t                   port_connect;
} ether_control_t;

typedef struct
{
    const ether_control_t * pether_control;
    uint32_t              phy_access;
} ether_ch_control_t;

    R_PRAGMA_PACKOPTION

[関連リンク]

クローバーフィールド.jp/_pragma演算子を使ってみた。
embedded.cloverfield.jp/2016/04/12/_pragma演算子ではまりました。
infocenter.arm.com/help/topic/com.arm.doc.dui0472ij/BABDIJDD.html
cpprefjp.github.io/lang/cpp11/pragma_operator.html
Google検索: _Pragma

[補足]

gcc-renesas.comのドキュメントには記載無いがGCC本家のドキュメントの#pragma pack(1) / #pragma pack()が使えました。(実はiodefine.hでも使われていました。)

GNURX
gcc-renesas.com/migration-guides/rx/index.html#Compiler_directives

GCC本家
gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/Structure_002dPacking-Pragmas.html#Structure_002dPacking-Pragmas
 

  • こんにちは。NoMaYです。

    ワーニングレベルを上げてFITモジュールをコンパイルしていて気付いたことがありました。(少なくとも)最新版では以下の未使用引数のワーニングが表示されたのですが、引数を持つインラインアセンブラ関数に対してどうにも回避のやりようがない未使用引数のワーニングが表示されてしまうというCC-RXの困惑する仕様の件はあるのですが、ワーニングの数が以前と比べてずっと多くなっていました。調べてみたところ、どうも、ヘッダ側で条件コンパイルによりCC-RXでは未使用となっている関数に対して、Cソース側では条件コンパイルが設定されていなくて未使用関数に対してワーニングが出てしまっているようです。これは修正した方が良いように思いました。(私は、とりあえず、r_rx_intrinsic_functions.cをビルドから除外するようにしました。ただ、他のCソースにおいて、どうしても出てしまうものがあって、何か対策を考えたいところです。また、怪しげなマクロになりそうですが、、、)

    Description                                         Resource                      Location    Path                                        Type
    M0520826: Parameter "data" was never referenced     r_rx_intrinsic_functions.c    line 466    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "ret" was never referenced      r_rx_intrinsic_functions.c    line 482    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "data" was never referenced     r_rx_intrinsic_functions.c    line 518    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "ret" was never referenced      r_rx_intrinsic_functions.c    line 534    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "data" was never referenced     r_rx_intrinsic_functions.c    line 573    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "ret" was never referenced      r_rx_intrinsic_functions.c    line 589    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "data" was never referenced     r_rx_intrinsic_functions.c    line 628    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "data" was never referenced     r_rx_intrinsic_functions.c    line 644    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "ret" was never referenced      r_rx_intrinsic_functions.c    line 660    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "ret" was never referenced      r_rx_intrinsic_functions.c    line 696    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "bit" was never referenced      r_rx_intrinsic_functions.c    line 733    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "data" was never referenced     r_rx_intrinsic_functions.c    line 733    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "bit" was never referenced      r_rx_intrinsic_functions.c    line 751    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "data" was never referenced     r_rx_intrinsic_functions.c    line 751    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "bit" was never referenced      r_rx_intrinsic_functions.c    line 769    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "data" was never referenced     r_rx_intrinsic_functions.c    line 769    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "data" was never referenced     r_rx_intrinsic_functions.c    line 788    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "ret" was never referenced      r_rx_intrinsic_functions.c    line 804    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "data" was never referenced     r_rx_intrinsic_functions.c    line 840    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "ret" was never referenced      r_rx_intrinsic_functions.c    line 856    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "ret" was never referenced      r_rx_intrinsic_functions.c    line 892    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "cos" was never referenced      r_rx_intrinsic_functions.c    line 954    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "f" was never referenced        r_rx_intrinsic_functions.c    line 954    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "sin" was never referenced      r_rx_intrinsic_functions.c    line 954    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "atan2" was never referenced    r_rx_intrinsic_functions.c    line 977    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "hypot" was never referenced    r_rx_intrinsic_functions.c    line 977    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "x" was never referenced        r_rx_intrinsic_functions.c    line 977    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem
    M0520826: Parameter "y" was never referenced        r_rx_intrinsic_functions.c    line 977    /RTOSDemo_CCRX/src/smc_gen/r_bsp/mcu/all    C/C++ Problem

    ヘッダ側の例 (R_BSP_SetBPSW関数は条件コンパイル文によりICCRXでしか使用されないようになっている)

    /* ---------- Backup PSW (BPSW) ---------- */
    #if defined(__CCRX__)

    /* void set_bpsw(unsigned long data) */
    #define R_BSP_SET_BPSW(x)    set_bpsw((unsigned long)(x))
    /* unsigned long get_bpsw(void) */
    #define R_BSP_GET_BPSW()     get_bpsw()

    #elif defined(__GNUC__)

    /* void __builtin_rx_mvtc (int reg, int val) */
    #define R_BSP_SET_BPSW(x)    __builtin_rx_mvtc(0x8, (int)(x))
    /* int __builtin_rx_mvfc (int) */
    #define R_BSP_GET_BPSW()     (unsigned long)__builtin_rx_mvfc(0x8)

    #elif defined(__ICCRX__)

    /* void R_BSP_SetBPSW(uint32_t data) (This macro uses API function of BSP.) */
    #define R_BSP_SET_BPSW(x)    R_BSP_SetBPSW((uint32_t)(x))
    /* uint32_t R_BSP_GetBPSW(void) (This macro uses API function of BSP.) */
    #define R_BSP_GET_BPSW()     R_BSP_GetBPSW()

    #endif

    Cソース側の例 (R_BSP_SetBPSW関数に対して条件コンパイル文が存在していない)

    R_BSP_PRAGMA_INLINE_ASM(R_BSP_SetBPSW)
    void R_BSP_SetBPSW(uint32_t data)
    {
        R_BSP_ASM_INTERNAL_USED(data)

        R_BSP_ASM_BEGIN
        R_BSP_ASM(    MVTC    R1, BPSW    )
        R_BSP_ASM_END
    } /* End of function R_BSP_SetBPSW() */

     

  • こんにちは。NoMaYです。

    IARコンパイラでワーニングレベルを上げてFITモジュールをコンパイルしてみて、CC-RX/GNURX/ICCRX共通化インラインアセンブラ記述マクロでワーニングが出てしまうことに気付きました。これについては、以下のように共通化マクロを変更したところ、コンパイルオプションで個別ワーニング抑止指定を設定しなくても、抑止することが出来るようになりました。(もっとも、何がしかの設定をしませんと、ワーニング検出箇所が多過ぎたり、エラー扱いされてしまって厳し過ぎたり、ということで後々大変になりますので、どうせ何がしかの設定をしないといけないのであれば、マクロ定義をややこしくするまでも無いのではないか、という考え方もあるかとは思いましたけれど、、、) これはFITモジュール側での採用を働きかけたいですね、、、

    EWRXでワーニングレベルを上げる設定の画面コピー (CC-RXはインフォメーションメッセージですがICCRXはリマークメッセージでした)


    EWRXでワーニングレベルを上げると表示されるワーニング(というかリマーク)メッセージの例(ちなみに他の箇所にも大量に表示されます)

    リマーク[Pe007]: unrecognized token C:\Renesas\...\r_bsp_common.c 108 
    リマーク[Pe007]: unrecognized token C:\Renesas\...\r_bsp_common.c 109
    リマーク[Pe007]: unrecognized token C:\Renesas\...\r_bsp_common.c 110
    リマーク[Pe007]: unrecognized token C:\Renesas\...\r_bsp_common.c 111
    リマーク[Pe010]: "#" not expected here C:\Renesas\...\r_bsp_common.c 112
    リマーク[Pe010]: "#" not expected here C:\Renesas\...\r_bsp_common.c 112
    リマーク[Pe007]: unrecognized token C:\Renesas\...\r_bsp_common.c 112
    リマーク[Pe007]: unrecognized token C:\Renesas\...\r_bsp_common.c 113
    リマーク[Pa174]: inline assembler statement has no declared side-effect. All optimizations around it will be disabled.  C:\Renesas\...\r_bsp_common.c 107
    Either add side-effect declarations or add volatile.



    変更対象: src/smc_gen/r_bsp/mcu/all/r_rx_compiler.h

    変更前

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

    #define R_BSP_ASM(...)            /* none */
    #define R_BSP_ASM_LAB_NEXT(n)     /* none */
    #define R_BSP_ASM_LAB_PREV(n)     /* none */
    #define R_BSP_ASM_LAB(n_colon)    /* none */
    #define R_BSP_ASM_BEGIN           /* none */
    #define R_BSP_ASM_END             /* none */

    #else

    #if defined(__CCRX__)

    #if !defined(__cplusplus)
    #define R_BSP_ASM(...)            __VA_ARGS__
    #else
    /* CC-RX' C++ mode does not support variadic macros */
    #endif
    #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           /* none */
    #define R_BSP_ASM_END             /* none */

    #elif defined(__GNUC__)

    #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__)

    #define _R_BSP_ASM(...)           #__VA_ARGS__
    #define R_BSP_ASM(...)            _R_BSP_ASM(__VA_ARGS__\n)
    #define R_BSP_ASM_LAB_NEXT(n)     _lab##n
    #define R_BSP_ASM_LAB_PREV(n)     _lab##n
    #define R_BSP_ASM_LAB(n_colon)    R_BSP_ASM(_lab##n_colon)
    #define R_BSP_ASM_BEGIN           asm(
    #define R_BSP_ASM_END             );

    #endif

    #endif /* defined(__CDT_PARSER__) */

    変更後

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

    。。。略。。。

    #else

    #if defined(__CCRX__)

    。。。略。。。

    #elif defined(__GNUC__)

    。。。略。。。

    #elif defined(__ICCRX__)

    #define _R_BSP_ASM(...)           #__VA_ARGS__ "\n"    ← ちなみにGNURXもこれで可でした
    #define R_BSP_ASM(...)            _R_BSP_ASM(__VA_ARGS__)    ← ちなみにGNURXもこれで可でした
    #define R_BSP_ASM_LAB_NEXT(n)     _lab##n
    #define R_BSP_ASM_LAB_PREV(n)     _lab##n
    #define R_BSP_ASM_LAB(n_colon)    R_BSP_ASM(_lab##n_colon)
    #define R_BSP_ASM_BEGIN           R_BSP_PRAGMA(diag_suppress = Pa174)\
                                      R_BSP_PRAGMA(diag_suppress = Pe010)\
                                      __asm volatile(
    #define R_BSP_ASM_END             );\
                                      R_BSP_PRAGMA(diag_default = Pe010)\
                                      R_BSP_PRAGMA(diag_default = Pa174)

    #endif

    #endif /* defined(__CDT_PARSER__) */

    変更後はEWRXで該当箇所でのワーニング(というかリマーク)メッセージの表示は抑止されるようになりました


    ちなみに、CC-RXでもワーニングレベルを上げてFITモジュールをコンパイルした時には、CC-RX/GNURX/ICCRX共通化インラインアセンブラ記述マクロでワーニングが出てしまいます。IARコンパイラでは#pragmaで個別ワーニング抑止指定(と解除指定)が出来ますが、CC-RXではそれが出来ませんので、コンパイルオプションで個別ワーニング抑止指定を設定して抑止することになります。

    CS+でワーニングレベルを上げると該当マクロ起因で表示されるワーニング(というかインフォーメーション)メッセージの例

    src\smc_gen\r_bsp\mcu\all\r_bsp_common.c(112):M0520010:"#" not expected here



    CS+でワーニングレベルを上げた時に該当マクロ起因で表示されるワーニング(というかインフォーメーション)メッセージを抑止する設定の画面コピー


    #しばらく前から、日本語Windows10上でCS+を英語モード表示(というか起動)させる方法を試していますが、その影響で、画面コピーではメニューやファンクションキーの表示がおかしくなっています。気にしないで下さい。

  • NoMaYさん

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

    本件改善を考えたいと思います。BSP開発チームに情報展開しました。
    進展がありましたら、また書き込みます。

    以上です
  • こんにちは。NoMaYです。

    すみません、そういえば、私は以下の案件をすっかり放置してしまっていました。週末、思い出してみます。(1年以上前の案件ですね、、、)

    現在、FITのBSPモジュールには以下のスレッドへの投稿を発展させた形でCC-RX/GNURX/ICCRX共通化割り込み関数定義マクロが組み込まれていますが、その影響で以下のFITのDTCモジュールのドキュメントに記載されているように、GNURXで未使用の変数/関数を削除するリンク最適化が出来なくなっていることを把握しました。(確かに以前に何かおかしなことがあるかもと感じたことがあった記憶はあるのですが、他のことに気を取られていて、深く追求しなかった記憶があります。) 今回、別スレッドでFreeRTOSのRTOSDemoプログラムを作成する傍ら、対策を考えてみました。(GNU ld側で対処する手もあるとは思いますが、、、) 取り敢えずの応急処置は、リンカスクリプトlinker_script.ldに以下の赤文字箇所を追加することかと思います。ただ、関数の名前の付け方だけに頼るのはトラブルの元だと思いますので、r_rx_compiler.hのマクロを改造して併用する方法を模索中です。

    GUNRX用プロジェクトにFITモジュールを組み込む方法について
    japan.renesasrulz.com/cafe_rene/f/forum5/4860/gunrx-fit/27041#27041

    ●リンカスクリプトlinker_script.ldに以下の赤文字箇所を追加する(他の箇所に関して思うところがあるのは別途)

    src/linker_script.ld

        .text 0xFFC00000: AT(0xFFC00000)
        {
            *(.text)
            KEEP(*(.text.*ISR))
            KEEP(*(.text.*_isr))
            KEEP(*(.text.*_interrupt))
            *(.text.*)
            *(P)
            etext = .;
        } > ROM

    RXファミリ DTCモジュール Firmware Integration Technology
    www.renesas.com/ja-jp/search/keyword-search.html#genre=document&q=r01an1819

    r01an1819jj0350-rx-dtc-dmac2.pdf

     

  • こんにちは。NoMaYです。

    別スレッドへ投稿していて今ようやく気付いたのですが、CGコンポーネントの中に以下のような名前になっていない割り込み関数がありますね。

    その別スレッド

    RXv3コアのレジスタ一括退避機能の使い方(Register Bank Save Function Usage)を調べてみるスレッド
    community-ja.renesas.com/cafe_rene/forums-groups/mcu-mpu/rx/f/forum5/9572/rxv3-register-bank-save-function-usage/47234#47234


    今まで私が知っていた割り込み関数名

        *ISR
        *_isr
        *_interrupt

     
    そのような名前になっていない割り込み関数名

       r_Config_MTU3_MTU4_CrestInterrupt

     

    すみません、すみません、いつまで以下の案件を放置しておくつもりなのだ!、というところですね。しかもモタモタしていた間に、e2 studio 2022-10で-gc-sectionを設定しようとしても強制的に解除されてしまう?ような振る舞いが見受けられるのようになってしまいました。まだ、条件は分かっていませんけれども、、、(あと、-Wの設定も幾つかがe2 studio 2022-10で設定しようとしても強制的に解除されてしまう?ような振る舞いも見受けられるようになってしまいました。まだ、条件は分かっていませんけれども、、、)

    すみません、そういえば、私は以下の案件をすっかり放置してしまっていました。週末、思い出してみます。(1年以上前の案件ですね、、、)

    現在、FITのBSPモジュールには以下のスレッドへの投稿を発展させた形でCC-RX/GNURX/ICCRX共通化割り込み関数定義マクロが組み込まれていますが、その影響で以下のFITのDTCモジュールのドキュメントに記載されているように、GNURXで未使用の変数/関数を削除するリンク最適化が出来なくなっていることを把握しました。(確かに以前に何かおかしなことがあるかもと感じたことがあった記憶はあるのですが、他のことに気を取られていて、深く追求しなかった記憶があります。) 今回、別スレッドでFreeRTOSのRTOSDemoプログラムを作成する傍ら、対策を考えてみました。(GNU ld側で対処する手もあるとは思いますが、、、) 取り敢えずの応急処置は、リンカスクリプトlinker_script.ldに以下の赤文字箇所を追加することかと思います。ただ、関数の名前の付け方だけに頼るのはトラブルの元だと思いますので、r_rx_compiler.hのマクロを改造して併用する方法を模索中です。

    GUNRX用プロジェクトにFITモジュールを組み込む方法について
    japan.renesasrulz.com/cafe_rene/f/forum5/4860/gunrx-fit/27041#27041

    ●リンカスクリプトlinker_script.ldに以下の赤文字箇所を追加する(他の箇所に関して思うところがあるのは別途)

    src/linker_script.ld

        .text 0xFFC00000: AT(0xFFC00000)
        {
            *(.text)
            KEEP(*(.text.*ISR))
            KEEP(*(.text.*_isr))
            KEEP(*(.text.*_interrupt))
            *(.text.*)
            *(P)
            etext = .;
        } > ROM

    RXファミリ DTCモジュール Firmware Integration Technology
    www.renesas.com/ja-jp/search/keyword-search.html#genre=document&q=r01an1819

    r01an1819jj0350-rx-dtc-dmac2.pdf


    以下、引用した本スレッド内の投稿のURLと更にその中で引用した本スレッド内の投稿のURLのメモです。([追記] 引用中の NoMaY said: をクリックすると飛べましたね。)

    community-ja.renesas.com/cafe_rene/forums-groups/mcu-mpu/rx/f/forum5/5079/cc-rx-gnurx-c99-_pragma-fit/39602#39602

    community-ja.renesas.com/cafe_rene/forums-groups/mcu-mpu/rx/f/forum5/5079/cc-rx-gnurx-c99-_pragma-fit/35290#35290
     

  • こんにちは。NoMaYです。

    くだんのCGコンポーネントの割り込み関数に関しては以下のように KEEP(*(.text.*Interrupt)) を追加すれば対処することが出来ます。なお、FreeRTOSのカーネルとデモプログラムへ対処したのが KEEP(*(.text.*ISR)) だったのですけれども、Azure RTOSのカーネルはどうなのか気になって確認してみました。以下のスレッドにCC-RXの場合について投稿していたソースと同じ様に、GNURXの場合もAzure RTOSのカーネルの割り込み関数のソースはアセンブラ記述になっていて、そのセクション名は .text となっていまして、現状では、FreeRTOSのカーネルやFIT/CGとは同じ様には扱えないことが分かりました。つまり、ソースにパッチを当ててセクション名を変更して同じ応急処置方法に嵌め込む、ようにする必要がありそうです。(なので、現状では、そのままのAzure RTOSカーネルソースでGNURXを使用するのならば、やはり -gc-section を諦めないといけない、ということになりそうです。(現状の回避策のまま。))

    Azure RTOSカーネルのCC-RXの場合の割り込み関数

    Azure RTOSでRXマイコンが使えるようになったのですね
    community-ja.renesas.com/cafe_rene/forums-groups/tools/f/forum21/6995/azure-rtos-rx/46908#46908

    libs/threadx/ports/rxv3/ccrx/src/tx_thread_schedule.src (こちらは割り込みルーチンです)

    ; Software triggered interrupt used to perform context switches.
    ; The priority of this interrupt is set to the lowest priority within
    ; tx_initialize_low_level() and triggered by ThreadX when calling
    ; _tx_thread_system_return().
    .RVECTOR 27, _tx_software_interrupt_entry
    .GLB _tx_software_interrupt_entry
    _tx_software_interrupt_entry:

        PUSHM R1-R2

        BSR __tx_thread_context_save

        BRA __tx_thread_context_restore



    Azure RTOSカーネルのGNURXの場合の割り込み関数

    lib/threadx/ports/rxv3/gnu/src/tx_thread_schedule.S (現状のソースです)
    (該当箇所のセクション名を .text.tx_software_interrupt_entry にして応急処置する?)

    ... 途中省略 ...

        .text


    ... 途中省略 ...

    ; Software triggered interrupt used to perform context switches.
    ; The priority of this interrupt is set to the lowest priority within
    ; tx_initialize_low_level() and triggered by ThreadX when calling
    ; _tx_thread_system_return().
    .global $tableentry$27$.rvectors
    $tableentry$27$.rvectors:

        PUSHM R1-R2

        BSR __tx_thread_context_save

        BRA __tx_thread_context_restore

    ... 途中省略 ...

     
    Azure RTOS以外の場合(FreeRTOSもしくはRTOS未使用)の場合の応急処置

    src/linker_script.ld

        .text 0xFFC00000: AT(0xFFC00000)
        {
            *(.text)
            KEEP(*(.text.*_isr))       /* for FIT */
            KEEP(*(.text.*_interrupt)) /* for CG */
            KEEP(*(.text.*Interrupt))  /* for CG Motor Component */
            KEEP(*(.text.*ISR))        /* for FreeRTOS Kernel and Demos */
            *(.text.*)
            *(P)
            etext = .;
        } > ROM

     

  • こんにちは。NoMaYです。

    モタモタしているうちに、こんなことになってしまいました。すべて私の不徳の致すところです。すみません。

    Release Notes: GCC 8.3.0.202204-GNURX
    llvm-gcc-renesas.com/release-notes/rx/latest/8.3.0.202204/release_notes.pdf

    CHANGES IN THE GCC 8.3.0.202204-GNURX

    This section describes the fixes made in the GCC 8.3.0.202204-GNURX release.

    GCC:

    1. [Improvement] DCMR register not getting saved/restored on function entry/exit
    In the current release, the DCMR register will be saved on function entry and restored on function exit.

    2. [Improvement] Negated floats getting promoted to double
    In previous releases, negation of floats resulted in their promotion to double, generating sub-optimal code if doubles were represented on 8 bytes.
    In the current release of the compiler, promotion will no longer happen when negating floats.

    3. [Deprecation] Automatic interrupt vector entry generation
    Declaring interrupt handlers with a numeric argument resulted in the compiler creating additional symbols, which could be referenced in the linker script to initialize the interrupt vector.
    This feature is being deprecated and removed in a future release, since the current implementation does not work when paired with the -gc-section command line option.


  • こんにちは。NoMaYです。

    どうすれば適切だったのかなぁ、、、(会社が倒産した後で、あれこれと考えているところの経営者の気持ち?)

    ● もっと早い時期に回避策をワールドワイドなサイトに報告すべきだった?

    ● そもそも、もっと早い時期にユーザとして問題提起をワールドワイドなサイトにすべきだった?

    ● モタモタしたひとつの要因は、FITモジュールではくだんの小細工で対処出来るが、CGコンポーネントでは対処不可だった

  • こんにちは。NoMaYです。

    仮に、まだ機会があるとして続きを考えるなら、応急処置以上のやり方として以下の考えが思い浮かびました。

    (1) 割り込みベクタに登録する割り込み関数は .isrtext.関数名 (もしもアセンブラソースなどで関数名を付けたくなければ .isrtext) というセクション名にする
    (2) リンカスクリプトには以下のように記述する
    (3) これらは、FITモジュールであればr_rx_compiler.hのくだんのマクロ定義にて、CGコンポーネントであればr_cg_interrupt_handlers.hへRXスマートコンフィグレータにて、自動的に設定する
    (4) リンカスクリプトに対しても、RXスマートコンフィグレータが自動的に設定する

    src/linker_script.ld

        .text 0xFFC00000: AT(0xFFC00000)
        {
            *(.text)
            /* for backward compatibility */
            KEEP(*(.text.*_isr))       /* for FIT */
            KEEP(*(.text.*_interrupt)) /* for CG */
            KEEP(*(.text.*Interrupt))  /* for CG Motor Component */
            KEEP(*(.text.*ISR))        /* for FreeRTOS Kernel and Demos */
            *(.text.*)
            /* for updated FIT, CG and RX SmartConfigurator */
            KEEP(*(.isrtext))
            KEEP(*(.isrtext.*))
            *(P)
            etext = .;
        } > ROM

     

  • こんにちは。NoMaYです。

    幸い、今回のGNURXの件は再検討して貰えることになりました。また、可能性として昔の投稿で一言だけ書いたGNU ld側で対処する手も当時よりは現実味が増したかも知れないかも、とも思うようになりました。(堅実さという点では、この対処が一番だとは思っているのですけれども、難易度が予想出来ないです。) 他方で、私の考えに思い浮かんだ案は、難易度は高くないのと、別スレッドで話題にしているRXスマートコンフィグレータの多重割り込み対応を改善しようとする時には思い浮かんだ案とちょうど同じ場所を触ることになるだろうという予想もあって、もう少し補足したいと思います。

    1つ前の投稿の以下の件の具体的な箇所は以下の通りです。

    > (3) これらは、FITモジュールであればr_rx_compiler.hのくだんのマクロ定義にて、CGコンポーネントであればr_cg_interrupt_handlers.hへRXスマートコンフィグレータにて、自動的に設定する

    r_rx_compiler.hのくだんのマクロ定義

    現状:

    #elif defined(__GNUC__)

    /* 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(__GNUC__)

    /* Standard */
    #define R_BSP_PRAGMA_INTERRUPT(function_name, vector)                 extern void function_name(void) __attribute__((interrupt(R_BSP_SECNAME_INTVECTTBL, vector), section(".isrtext." #function_name)));
    #define R_BSP_PRAGMA_STATIC_INTERRUPT(function_name, vector)          static void function_name(void) __attribute__((interrupt(R_BSP_SECNAME_INTVECTTBL, vector), section(".isrtext." #function_name), 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), section(".isrtext." #function_name))) \
                                                                                                          __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), section(".isrtext." #function_name), 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"), section(".isrtext." #function_name)));
    #define R_BSP_PRAGMA_STATIC_INTERRUPT_DEFAULT(function_name)          static void function_name(void) __attribute__((interrupt(R_BSP_SECNAME_INTVECTTBL, "$default"), section(".isrtext." #function_name), used));

     
    r_cg_interrupt_handlers.hの一例

    現状:

    /* RIIC0 RXI0 */
    void r_Config_RIIC0_receive_interrupt(void) __attribute__ ((interrupt(".rvectors",VECT(RIIC0,RXI0))));

    /* RIIC0 TXI0 */
    void r_Config_RIIC0_transmit_interrupt(void) __attribute__ ((interrupt(".rvectors",VECT(RIIC0,TXI0))));

    /* SCI0 RXI0 */
    void r_Config_SCI0_receive_interrupt(void) __attribute__ ((interrupt(".rvectors",VECT(SCI0,RXI0))));

    /* SCI0 TXI0 */
    void r_Config_SCI0_transmit_interrupt(void) __attribute__ ((interrupt(".rvectors",VECT(SCI0,TXI0))));

    など

     
    変更案: (変更箇所(というか追加箇所)を赤文字にしています)

    /* RIIC0 RXI0 */
    void r_Config_RIIC0_receive_interrupt(void) __attribute__ ((interrupt(".rvectors",VECT(RIIC0,RXI0)), section(".isrtext.r_Config_RIIC0_receive_interrupt")));

    /* RIIC0 TXI0 */
    void r_Config_RIIC0_transmit_interrupt(void) __attribute__ ((interrupt(".rvectors",VECT(RIIC0,TXI0)), section(".isrtext.r_Config_RIIC0_transmit_interrupt")));

    /* SCI0 RXI0 */
    void r_Config_SCI0_receive_interrupt(void) __attribute__ ((interrupt(".rvectors",VECT(SCI0,RXI0)), section(".isrtext.r_Config_SCI0_receive_interrupt")));

    /* SCI0 TXI0 */
    void r_Config_SCI0_transmit_interrupt(void) __attribute__ ((interrupt(".rvectors",VECT(SCI0,TXI0)), section(".isrtext.r_Config_SCI0_transmit_interrupt")));

    など