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
 

Parents
  • NoMaYさん

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

    _Pragma 使えそうですね。
    FITの活動ではマルチコンパイラ対応は私も継続して提案しておりました。
    開発リソースと対応優先度の兼ね合いから見送られてきましたが、
    Amazon FreeRTOSの件もあり、対応すべきという機運の高まりを感じます。
    FITのマルチコンパイラ対応を実現するとしたら、CC-RXに加えて、GCCとIARの3点になります。

    _Pragmaを教えていただく前までは、各ソフトにおいてpragmaなりコンパイラ依存のコードがある個所を
    すべてifdefで分岐させるつもりでしたが、この方式でそれが不要になりそうですね。
    IARでも_Pragmaが使えそうなことを確認しました。

    情報提供いただきありがとうございます。
    ちょっとBSP、Ether、CMT、TCP/IPの組み合わせで1コード3コンパイラ対応ができるか
    実験してみようと思います。

    以上です
  • シェルティさん、こんにちは。NoMaYです。

    私は、この後、以前に別スレッド『GUNRX用プロジェクトにFITモジュールを組み込む方法について』に投稿したGNURXの割り込み関数の記述方法を、これと組み合わせてみようかと思っています。(ちなみに、IARコンパイラでCC-RXのような割り込み関数の記述方法、つまり、割り込み関数のアドレスを設定した割り込みベクタの配列を用意する必要が無く、割り込み関数をグローバルにする必要が無い、が出来るかどうか気になるところです。)

Reply
  • シェルティさん、こんにちは。NoMaYです。

    私は、この後、以前に別スレッド『GUNRX用プロジェクトにFITモジュールを組み込む方法について』に投稿したGNURXの割り込み関数の記述方法を、これと組み合わせてみようかと思っています。(ちなみに、IARコンパイラでCC-RXのような割り込み関数の記述方法、つまり、割り込み関数のアドレスを設定した割り込みベクタの配列を用意する必要が無く、割り込み関数をグローバルにする必要が無い、が出来るかどうか気になるところです。)

Children
No Data