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です。

    > 幸い、今回のGNURXの件は再検討して貰えることになりました。

    最新版が出ていたので見てみたら取り消して貰えていました。以下のリリースノートで引用されているWikiには回避策が2つ提示されていて、2つ目の方が私が投稿していたもの、他方、1つ目の方は新しい回避策で2つ目より汎用的に適用可能なもの、となっていました。1つ目の方はFITのBSPモジュールに取り込んで貰えるといいなぁ、と思いました。

    Release Notes: GCC 8.3.0.202305-GNURX
    llvm-gcc-renesas.com/release-notes/rx/latest/8.3.0.202305/release_notes.pdf#page=2

    CHANGES IN THE GCC 8.3.0.202305-GNURX

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

    …略…

    7. [Un-deprecation] Automatic interrupt vector entry generation

    The GCC 8.3.0.202204-GNURX release deprecated automatic interrupt vector entry generation, due to concerns about how it would interfere with linker garbage collection (`--gc-sections`).
    We have identified two workarounds that permit the use of --gc-sections in conjunction with automatic interrupt vector entry generation, which we have documented here: https://llvm-gcc-renesas.com/wiki/index.php?title=RX_automatic_interrupt_vector_entry_usage
    Consequently the deprecation warning

    …略…


    rx-driver-package

    github.com/renesas/rx-driver-package/blob/master/source/r_bsp/r_bsp_vx.xx/r_bsp/mcu/all/linker_script_rvectors.inc
    ↑の記述に対応して、↓のアセンブラソースの他にWikiの以下のアセンブラソースを追加しておけば良い、のかな。
    github.com/renesas/rx-driver-package/blob/master/source/r_bsp/r_bsp_vx.xx/r_bsp/mcu/all/reset_program.S

    int-guard.s

    .section .intvecguard
    .weak $tableentry$0$vect
    .word $tableentry$0$vect
    .weak $tableentry$1$vect
    .word $tableentry$1$vect
    .weak $tableentry$2$vect
    .word $tableentry$2$vect
    ...
    .weak $tableentry$255$vect
    .word $tableentry$255$vect

     
    そして、Wikiの以下の記述をリンカスクリプトに反映させる方法ですけれども、RXスマートコンフィグレータのリンカスクリプトのテンプレートに追加しておけば良い、のかな。

        .intvecguard :
        {
            KEEP(*(.intvecguard))
        }

     
    [追記]

    直感、でしかないですけれども、ソースは以下にしておくと安全かも知れないような気もしなくもないような。

    interrupt_guard.S ← 少なくともハイフンよりアンダースコアの方が、、、

    #include "r_bsp_config.h"

        .if __GNUC__

        .list ← これは、単にreset_program.Sに合わせた、だけです。
    .section .intvecguard
    .weak $tableentry$0$vect
    .word $tableentry$0$vect
    .weak $tableentry$1$vect
    .word $tableentry$1$vect
    .weak $tableentry$2$vect
    .word $tableentry$2$vect
    ...
    .weak $tableentry$255$vect
    .word $tableentry$255$vect

        .endif

        .end