こんにちは。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_PACKtypedef 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.htmlcpprefjp.github.io/lang/cpp11/pragma_operator.htmlGoogle検索: _Pragma[補足]gcc-renesas.comのドキュメントには記載無いがGCC本家のドキュメントの#pragma pack(1) / #pragma pack()が使えました。(実はiodefine.hでも使われていました。)GNURXgcc-renesas.com/migration-guides/rx/index.html#Compiler_directivesGCC本家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-GNURXllvm-gcc-renesas.com/release-notes/rx/latest/8.3.0.202305/release_notes.pdf#page=2「CHANGES IN THE GCC 8.3.0.202305-GNURXThis section describes the fixes made in the GCC 8.3.0.202305-GNURX release.…略…7. [Un-deprecation] Automatic interrupt vector entry generationThe 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_usageConsequently the deprecation warning…略…」rx-driver-packagegithub.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.Sint-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