こんにちは。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です。私は、この後、以前に別スレッド『GUNRX用プロジェクトにFITモジュールを組み込む方法について』に投稿したGNURXの割り込み関数の記述方法を、これと組み合わせてみようかと思っています。(ちなみに、IARコンパイラでCC-RXのような割り込み関数の記述方法、つまり、割り込み関数のアドレスを設定した割り込みベクタの配列を用意する必要が無く、割り込み関数をグローバルにする必要が無い、が出来るかどうか気になるところです。)
こんにちは。NoMaYです。今度は#pragma inlineについて考えてみました。CC-RXのヘルプを読んでいて気付いたことは、FITが前提としているC99仕様では、以下のようなCC-RXとGNURXに共通なマクロを用意するのが良いのではないかということです。
#define R_ATTRIB_INLINE inline extern#define R_ATTRIB_STATIC_INLINE inline static#define R_PRAGMA_INLINE(function_prototype) R_ATTRIB_INLINE function_prototype;#define R_PRAGMA_STATIC_INLINE(function_prototype) R_ATTRIB_STATIC_INLINE function_prototype;
そうすれば、以下のようなCC-RXとGNURXで共通な記述に出来ると思います。(ただ、この関数に限りませんが、ファイル間インライン展開される為にはコンパイル時に大域最適化オプション-merge_filesが必要だという点がFITのプログラマの人達に認識されていないような気がします。この件はスレッドを分けようかと思います。[追記] 別スレッド『FITのソースを見ていて気付いたCC-RXの仕様をプログラマが勘違いしている気がするコード』に分けました。)例) r_sci_rx.c現状
#pragma inline(R_SCI_GetVersion)uint32_t R_SCI_GetVersion(void){uint32_t const version = (SCI_VERSION_MAJOR << 16) | SCI_VERSION_MINOR; return version;} /* End of function R_SCI_GetVersion() */
共通化案
R_PRAGMA_INLINE(uint32_t R_SCI_GetVersion(void))uint32_t R_SCI_GetVersion(void){uint32_t const version = (SCI_VERSION_MAJOR << 16) | SCI_VERSION_MINOR; return version;} /* End of function R_SCI_GetVersion() */
もしくは
R_ATTRIB_INLINEuint32_t R_SCI_GetVersion(void){uint32_t const version = (SCI_VERSION_MAJOR << 16) | SCI_VERSION_MINOR; return version;} /* End of function R_SCI_GetVersion() */
以下のCC-RXのC99仕様のinline指定子に関する赤文字の挙動はGNURXでも同じ(というか常に生成される?)でした。([追記] 念の為に確認したらCC-RXでも常に生成されたので調べてみたら、プロトタイプ宣言があった場合にも生成されるようでした。)4.2.4 拡張仕様の使用方法 - CS+ V6.01.00 > コンパイラ編 > コンパイラ言語仕様 > 拡張言語仕様 > 拡張仕様の使用方法(4)関数のインライン展開記述tool-support.renesas.com/autoupdate/support/onlinehelp/ja-JP/csp/V6.01.00/CS+.chm/Compiler-CCRX.chm/Output/ccrx04c0204y.html#19230今までに投稿した内容を組み込んで、以下のヘッダファイルを作成してみました。SCFGcompiler.h
#ifndef SCFGCOMPILERS_H #define SCFGCOMPILERS_H /* https://gcc-renesas.com/migration-guides/rx/index.html#Compiler_directives https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html https://gcc.gnu.org/onlinedocs/gcc/RX-Function-Attributes.html https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html */ #if defined(__CCRX__) /* supported */ #elif defined(__GNUC__) /* supported */ #else #error "Unrecognized compiler" #endif #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 #if defined(__CCRX__) #define R_PRAGMA_INTERRUPT(function_name, vector) R_PRAGMA(interrupt function_name(vect=vector))\ extern void function_name(void); #define R_PRAGMA_STATIC_INTERRUPT(function_name, vector) R_PRAGMA(interrupt function_name(vect=vector))\ static void function_name(void); //TODO: fast interrupt #elif defined(__GNUC__) #define R_PRAGMA_INTERRUPT(function_name, vector) extern void function_name(void) __attribute__((interrupt(".rvectors", vector))); #define R_PRAGMA_STATIC_INTERRUPT(function_name, vector) static void function_name(void) __attribute__((interrupt(".rvectors", vector), used)); //TODO: fast interrupt #endif #define R_ATTRIB_INLINE inline extern #define R_ATTRIB_STATIC_INLINE inline static #define R_PRAGMA_INLINE(function_prototype) R_ATTRIB_INLINE function_prototype; #define R_PRAGMA_STATIC_INLINE(function_prototype) R_ATTRIB_STATIC_INLINE function_prototype; #if defined(__CCRX__) /* nothing to do */ #elif defined(__GNUC__) #define __evenaccess /* none */ #endif /* https://gcc-renesas.com/migration-guides/rx/index.html#Compiler_predefined */ #if defined(__CCRX__) /* maybe nothing to do */ #elif defined(__GNUC__) #define __RX 1 #if defined(__RX_LITTLE_ENDIAN__) #define __LIT 1 #endif #if defined(__RX_BIG_ENDIAN__) #define __BIG 1 #endif #endif #endif /* SCFGCOMPILERS_H */
こんにちは。NoMaYです。今度は#pragma bit_orderについて考えてみました。FITのソースには以下のような記述があります。残念ながらGNURXに(というかGCC本家にも)相当する機能はありませんでした。そこで、この#pragma単体ではなく、着目するソース範囲を少し広げて、マクロを考えてみました。例) r_flash_rx65n.h現状
#pragma bit_order left#pragma unpacktypedef union{ unsigned long LONG; struct { unsigned long BTFLG:1; unsigned long :3; unsigned long FAWE:12; unsigned long FSPR:1; unsigned long :3; unsigned long FAWS:12; } BIT;} fawreg_t;#pragma bit_order#pragma packoption
R_PRAGMA_UNPACKtypedef union{ unsigned long LONG; R_BITFIELD_BIT_ORDER_LEFT_6( unsigned long BTFLG:1, unsigned long :3, unsigned long FAWE:12, unsigned long FSPR:1, unsigned long :3, unsigned long FAWS:12 ) BIT;} fawreg_t;R_PRAGMA_PACKOPTION
考えたマクロ
#if defined(__CCRX__)略#define R_BITFIELD_BIT_ORDER_LEFT_6(bf1, bf2, bf3, bf4, bf5, bf6)\struct {\R_PRAGMA(bit_order left)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ bf5;\ bf6;\ };\R_PRAGMA(bit_order)\}略#elif defined(__GNUC__)#if defined(__RX_LITTLE_ENDIAN__)略#define R_BITFIELD_BIT_ORDER_LEFT_6(bf1, bf2, bf3, bf4, bf5, bf6)\struct {\ bf6;\ bf5;\ bf4;\ bf3;\ bf2;\ bf1;\}略#else略#define R_BITFIELD_BIT_ORDER_LEFT_6(bf1, bf2, bf3, bf4, bf5, bf6)\struct {\ bf1;\ bf2;\ bf3;\ bf4;\ bf5;\ bf6;\}略#endif#endif
なお、#pragma bit_orderの仕様は以下の通りです。4.2.4 拡張仕様の使用方法 - CS+ V6.01.00 > コンパイラ編 > コンパイラ言語仕様 > 拡張言語仕様 > 拡張仕様の使用方法(7)ビットフィールド並び順指定tool-support.renesas.com/autoupdate/support/onlinehelp/ja-JP/csp/V6.01.00/CS+.chm/Compiler-CCRX.chm/Output/ccrx04c0204y.html#53130ちなみに、今回の例の構造体(というかビットフィールド)の定義はiodefine.hに存在しているのですが、もっと大きな構造体の定義の一部となっており、それを利用する手段はないものかと考えてみたのですが、思い浮かびませんでした、、、CC-RX用iodefine.h
#pragma bit_order left#pragma unpack略typedef struct st_flash {略 union { unsigned long LONG; struct { unsigned long BTFLG:1; unsigned long :3; unsigned long FAWE:12; unsigned long FSPR:1; unsigned long :3; unsigned long FAWS:12; } BIT; } FAWMON;略} st_flash_t;略#pragma bit_order#pragma packoption
GNURX用iodefine.h
#pragma pack(4)略typedef struct st_flash {略 union { unsigned long LONG; struct { #ifdef __RX_LITTLE_ENDIAN__ unsigned long FAWS : 12; unsigned long : 3; unsigned long FSPR : 1; unsigned long FAWE : 12; unsigned long : 3; unsigned long BTFLG : 1;#else unsigned long BTFLG : 1; unsigned long : 3; unsigned long FAWE : 12; unsigned long FSPR : 1; unsigned long : 3; unsigned long FAWS : 12;#endif } BIT; } FAWMON;略} st_flash_t;略#pragma pack()
以下、前回投稿したヘッダファイルを更新しました。SCFGcompiler.h
#ifndef SCFGCOMPILERS_H #define SCFGCOMPILERS_H /* https://gcc-renesas.com/migration-guides/rx/index.html#Compiler_directives https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html https://gcc.gnu.org/onlinedocs/gcc/RX-Function-Attributes.html https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html */ #if defined(__CCRX__) /* supported */ #elif defined(__GNUC__) /* supported */ #elif defined(__ICCRX__) /* not supported yet */ #error "IAR RX compiler is not supported yet" /* http://netstorage.iar.com/SuppDB/Public/UPDINFO/007248/ew/doc/EWRX_MigratingFromRenesasHEWRX.pdf */ #else #error "Unrecognized compiler" #endif #define R_PRAGMA(...) _Pragma(#__VA_ARGS__) #if defined(__CCRX__) #define R_PRAGMA_PACK R_PRAGMA(pack) #define R_PRAGMA_UNPACK R_PRAGMA(unpack) #define R_PRAGMA_PACKOPTION R_PRAGMA(packoption) #elif defined(__GNUC__) #define R_PRAGMA_PACK R_PRAGMA(pack(1)) #define R_PRAGMA_UNPACK R_PRAGMA(pack(4)) #define R_PRAGMA_PACKOPTION R_PRAGMA(pack()) #endif #if defined(__CCRX__) #define R_PRAGMA_INTERRUPT(function_name, vector) R_PRAGMA(interrupt function_name(vect=vector))\ extern void function_name(void); #define R_PRAGMA_STATIC_INTERRUPT(function_name, vector) R_PRAGMA(interrupt function_name(vect=vector))\ static void function_name(void); //TODO: fast interrupt //TODO: exception (i.e. without vector) //TODO: vector only #elif defined(__GNUC__) #define R_PRAGMA_INTERRUPT(function_name, vector) extern void function_name(void) __attribute__((interrupt(".rvectors", vector))); #define R_PRAGMA_STATIC_INTERRUPT(function_name, vector) static void function_name(void) __attribute__((interrupt(".rvectors", vector), used)); //TODO: fast interrupt //TODO: exception (i.e. without vector) //TODO: vector only #endif //TODO: __attribute__((always_inline)) should be used for GNURX? #define R_ATTRIB_INLINE inline extern #define R_ATTRIB_STATIC_INLINE inline static #define R_PRAGMA_INLINE(function_prototype) R_ATTRIB_INLINE function_prototype; #define R_PRAGMA_STATIC_INLINE(function_prototype) R_ATTRIB_STATIC_INLINE function_prototype; #if defined(__CCRX__) #define R_BITFIELD_BIT_ORDER_LEFT_2(bf1, bf2)\ struct {\ R_PRAGMA(bit_order left)\ struct {\ bf1;\ bf2;\ };\ R_PRAGMA(bit_order)\ } #define R_BITFIELD_BIT_ORDER_LEFT_3(bf1, bf2, bf3)\ struct {\ R_PRAGMA(bit_order left)\ struct {\ bf1;\ bf2;\ bf3;\ };\ R_PRAGMA(bit_order)\ } #define R_BITFIELD_BIT_ORDER_LEFT_4(bf1, bf2, bf3, bf4)\ struct {\ R_PRAGMA(bit_order left)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ };\ R_PRAGMA(bit_order)\ } #define R_BITFIELD_BIT_ORDER_LEFT_5(bf1, bf2, bf3, bf4, bf5)\ struct {\ R_PRAGMA(bit_order left)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ bf5;\ };\ R_PRAGMA(bit_order)\ } #define R_BITFIELD_BIT_ORDER_LEFT_6(bf1, bf2, bf3, bf4, bf5, bf6)\ struct {\ R_PRAGMA(bit_order left)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ bf5;\ bf6;\ };\ R_PRAGMA(bit_order)\ } #define R_BITFIELD_BIT_ORDER_LEFT_7(bf1, bf2, bf3, bf4, bf5, bf6, bf7)\ struct {\ R_PRAGMA(bit_order left)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ bf5;\ bf6;\ bf7;\ };\ R_PRAGMA(bit_order)\ } #define R_BITFIELD_BIT_ORDER_LEFT_8(bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8)\ struct {\ R_PRAGMA(bit_order left)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ bf5;\ bf6;\ bf7;\ bf8;\ };\ R_PRAGMA(bit_order)\ } #define R_BITFIELD_BIT_ORDER_LEFT_9(bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, bf9)\ struct {\ R_PRAGMA(bit_order left)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ bf5;\ bf6;\ bf7;\ bf8;\ bf9;\ };\ R_PRAGMA(bit_order)\ } #elif defined(__GNUC__) #if defined(__RX_LITTLE_ENDIAN__) #define R_BITFIELD_BIT_ORDER_LEFT_2(bf1, bf2)\ struct {\ bf2;\ bf1;\ } #define R_BITFIELD_BIT_ORDER_LEFT_3(bf1, bf2, bf3)\ struct {\ bf3;\ bf2;\ bf1;\ } #define R_BITFIELD_BIT_ORDER_LEFT_4(bf1, bf2, bf3, bf4)\ struct {\ bf4;\ bf3;\ bf2;\ bf1;\ } #define R_BITFIELD_BIT_ORDER_LEFT_5(bf1, bf2, bf3, bf4, bf5)\ struct {\ bf5;\ bf4;\ bf3;\ bf2;\ bf1;\ } #define R_BITFIELD_BIT_ORDER_LEFT_6(bf1, bf2, bf3, bf4, bf5, bf6)\ struct {\ bf6;\ bf5;\ bf4;\ bf3;\ bf2;\ bf1;\ } #define R_BITFIELD_BIT_ORDER_LEFT_7(bf1, bf2, bf3, bf4, bf5, bf6, bf7)\ struct {\ bf7;\ bf6;\ bf5;\ bf4;\ bf3;\ bf2;\ bf1;\ } #define R_BITFIELD_BIT_ORDER_LEFT_8(bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8)\ struct {\ bf8;\ bf7;\ bf6;\ bf5;\ bf4;\ bf3;\ bf2;\ bf1;\ } #define R_BITFIELD_BIT_ORDER_LEFT_9(bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, bf9)\ struct {\ bf9;\ bf8;\ bf7;\ bf6;\ bf5;\ bf4;\ bf3;\ bf2;\ bf1;\ } #else #define R_BITFIELD_BIT_ORDER_LEFT_(bf1, bf2)\ struct {\ bf1;\ bf2;\ } #define R_BITFIELD_BIT_ORDER_LEFT_3(bf1, bf2, bf3)\ struct {\ bf1;\ bf2;\ bf3;\ } #define R_BITFIELD_BIT_ORDER_LEFT_4(bf1, bf2, bf3, bf4)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ } #define R_BITFIELD_BIT_ORDER_LEFT_5(bf1, bf2, bf3, bf4, bf5)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ bf5;\ } #define R_BITFIELD_BIT_ORDER_LEFT_6(bf1, bf2, bf3, bf4, bf5, bf6)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ bf5;\ bf6;\ } #define R_BITFIELD_BIT_ORDER_LEFT_7(bf1, bf2, bf3, bf4, bf5, bf6, bf7)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ bf5;\ bf6;\ bf7;\ } #define R_BITFIELD_BIT_ORDER_LEFT_8(bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ bf5;\ bf6;\ bf7;\ bf8;\ } #define R_BITFIELD_BIT_ORDER_LEFT_9(bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, bf9)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ bf5;\ bf6;\ bf7;\ bf8;\ bf9;\ } #endif #endif #if defined(__CCRX__) /* #define volatile volatile __evenaccess |* I guess this is a bad practice, but ... */ #elif defined(__GNUC__) #define __evenaccess /* none */ #endif /* https://gcc-renesas.com/migration-guides/rx/index.html#Compiler_predefined */ #if defined(__CCRX__) /* maybe nothing to do */ #elif defined(__GNUC__) #define __RX 1 #if defined(__RX_LITTLE_ENDIAN__) #define __LIT 1 #else #define __BIG 1 #endif #endif #endif /* SCFGCOMPILERS_H */
こんにちは。NoMaYです。今度は#pragma sectionについて考えてみました。FITのソースには以下のような記述があります。幸いなことにGNURXにも(というかGCC本家にも)相当する機能があります。とは言え、CC-RXとの構文の違いをどのようにラップしてソースの共通化に使えるマクロにするか悩ましいところがありましたが、以下のマクロを考えてみました。例1) r_ether_rx.c現状
/* * Receive, transmit descriptors and their buffer. They are * defined with section pragma directives to easily locate them * on the memory map. */#pragma section _RX_DESCstatic descriptor_t rx_descriptors[ETHER_CHANNEL_MAX][ETHER_CFG_EMAC_RX_DESCRIPTORS];#pragma section _TX_DESCstatic descriptor_t tx_descriptors[ETHER_CHANNEL_MAX][ETHER_CFG_EMAC_TX_DESCRIPTORS];/* * As for Ethernet buffer, the size of total buffer which are use for transmission and the reception is secured. * The total buffer's size which the value is integrated from EMAC_NUM_BUFFERS (buffer number) and * ETHER_CFG_BUFSIZE (the size of one buffer). * The ETHER_CFG_BUFSIZE and EMAC_NUM_BUFFERS are defined by macro in the file "r_ether_private.h". * It is sequentially used from the head of the buffer as a receive buffer or a transmission buffer. */#pragma section _ETHERNET_BUFFERSstatic etherbuffer_t ether_buffers[ETHER_CHANNEL_MAX];#pragma section
/* * Receive, transmit descriptors and their buffer. They are * defined with section pragma directives to easily locate them * on the memory map. */R_ATTRIB_SECTION_CHANGE(_RX_DESC)static descriptor_t rx_descriptors[ETHER_CHANNEL_MAX][ETHER_CFG_EMAC_RX_DESCRIPTORS];R_ATTRIB_SECTION_CHANGE(_TX_DESC)static descriptor_t tx_descriptors[ETHER_CHANNEL_MAX][ETHER_CFG_EMAC_TX_DESCRIPTORS];/* * As for Ethernet buffer, the size of total buffer which are use for transmission and the reception is secured. * The total buffer's size which the value is integrated from EMAC_NUM_BUFFERS (buffer number) and * ETHER_CFG_BUFSIZE (the size of one buffer). * The ETHER_CFG_BUFSIZE and EMAC_NUM_BUFFERS are defined by macro in the file "r_ether_private.h". * It is sequentially used from the head of the buffer as a receive buffer or a transmission buffer. */R_ATTRIB_SECTION_CHANGE(_ETHERNET_BUFFERS)static etherbuffer_t ether_buffers[ETHER_CHANNEL_MAX];R_ATTRIB_SECTION_CHANGE_END
例2) r_flash_type4.c現状
#if (FLASH_CFG_CODE_FLASH_ENABLE == 1)static flash_err_t flash_write_faw_reg(fawreg_t faw);#if (FLASH_IN_DUAL_BANK_MODE)#pragma section FRAM2flash_err_t flash_toggle_banksel_reg(){ 略}#endif // FLASH_IN_DUAL_BANK_MODE#pragma section FRAM#endif // #if (FLASH_CFG_CODE_FLASH_ENABLE == 1)flash_err_t get_cmdlk_err(void){ 略}略#if (FLASH_CFG_CODE_FLASH_ENABLE == 1)略flash_err_t flash_write_faw_reg (fawreg_t faw){ 略}略#pragma section // end FRAM#endif // FLASH_CFG_CODE_FLASH_ENABLE
#if (FLASH_CFG_CODE_FLASH_ENABLE == 1)static flash_err_t flash_write_faw_reg(fawreg_t faw);#if (FLASH_IN_DUAL_BANK_MODE)R_ATTRIB_SECTION_CHANGE(FRAM2)flash_err_t flash_toggle_banksel_reg(){ 略}#endif // FLASH_IN_DUAL_BANK_MODE#define FLASH_PE_MODE_SECTION R_ATTRIB_SECTION_CHANGE(FRAM)#define FLASH_SECTION_CHANGE_END R_ATTRIB_SECTION_CHANGE_END#else // #if (FLASH_CFG_CODE_FLASH_ENABLE == 1)#define FLASH_PE_MODE_SECTION#define FLASH_SECTION_CHANGE_END#endif // #if (FLASH_CFG_CODE_FLASH_ENABLE == 1)FLASH_PE_MODE_SECTIONflash_err_t get_cmdlk_err(void){ 略}略#if (FLASH_CFG_CODE_FLASH_ENABLE == 1)略FLASH_PE_MODE_SECTIONflash_err_t flash_write_faw_reg (fawreg_t faw){ 略}略FLASH_SECTION_CHANGE_END // end FRAM#endif // FLASH_CFG_CODE_FLASH_ENABLE
#if defined(__CCRX__)#define R_ATTRIB_SECTION_CHANGE(section_name) R_PRAGMA(section section_name)#define R_ATTRIB_SECTION_CHANGE_END R_PRAGMA(section)#elif defined(__GNUC__)#define R_ATTRIB_SECTION_CHANGE(section_name) __attribute__((section(#section_name)))#define R_ATTRIB_SECTION_CHANGE_END /* none */#endif
#ifndef SCFGCOMPILERS_H #define SCFGCOMPILERS_H /* https://gcc-renesas.com/migration-guides/rx/index.html#Compiler_directives https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html https://gcc.gnu.org/onlinedocs/gcc/RX-Function-Attributes.html https://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html */ #if defined(__CCRX__) /* supported */ #elif defined(__GNUC__) /* supported */ #elif defined(__ICCRX__) /* not supported yet */ #error "IAR RX compiler is not supported yet" /* http://netstorage.iar.com/SuppDB/Public/UPDINFO/007248/ew/doc/EWRX_MigratingFromRenesasHEWRX.pdf */ #else #error "Unrecognized compiler" #endif #define R_PRAGMA(...) _Pragma(#__VA_ARGS__) #if defined(__CCRX__) #define R_PRAGMA_PACK R_PRAGMA(pack) #define R_PRAGMA_UNPACK R_PRAGMA(unpack) #define R_PRAGMA_PACKOPTION R_PRAGMA(packoption) #elif defined(__GNUC__) #define R_PRAGMA_PACK R_PRAGMA(pack(1)) #define R_PRAGMA_UNPACK R_PRAGMA(pack(4)) #define R_PRAGMA_PACKOPTION R_PRAGMA(pack()) #endif #if defined(__CCRX__) #define R_PRAGMA_INTERRUPT(function_name, vector) R_PRAGMA(interrupt function_name(vect=vector))\ extern void function_name(void); #define R_PRAGMA_STATIC_INTERRUPT(function_name, vector) R_PRAGMA(interrupt function_name(vect=vector))\ static void function_name(void); //TODO: fast interrupt //TODO: exception (i.e. without vector) //TODO: vector only #elif defined(__GNUC__) #define R_PRAGMA_INTERRUPT(function_name, vector) extern void function_name(void) __attribute__((interrupt(".rvectors", vector))); #define R_PRAGMA_STATIC_INTERRUPT(function_name, vector) static void function_name(void) __attribute__((interrupt(".rvectors", vector), used)); //TODO: fast interrupt //TODO: exception (i.e. without vector) //TODO: vector only #endif //TODO: __attribute__((always_inline)) should be used for GNURX? #define R_ATTRIB_INLINE inline extern #define R_ATTRIB_STATIC_INLINE inline static #define R_PRAGMA_INLINE(function_prototype) R_ATTRIB_INLINE function_prototype; #define R_PRAGMA_STATIC_INLINE(function_prototype) R_ATTRIB_STATIC_INLINE function_prototype; #if defined(__CCRX__) #define R_BITFIELD_BIT_ORDER_LEFT_2(bf1, bf2)\ struct {\ R_PRAGMA(bit_order left)\ struct {\ bf1;\ bf2;\ };\ R_PRAGMA(bit_order)\ } #define R_BITFIELD_BIT_ORDER_LEFT_3(bf1, bf2, bf3)\ struct {\ R_PRAGMA(bit_order left)\ struct {\ bf1;\ bf2;\ bf3;\ };\ R_PRAGMA(bit_order)\ } #define R_BITFIELD_BIT_ORDER_LEFT_4(bf1, bf2, bf3, bf4)\ struct {\ R_PRAGMA(bit_order left)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ };\ R_PRAGMA(bit_order)\ } #define R_BITFIELD_BIT_ORDER_LEFT_5(bf1, bf2, bf3, bf4, bf5)\ struct {\ R_PRAGMA(bit_order left)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ bf5;\ };\ R_PRAGMA(bit_order)\ } #define R_BITFIELD_BIT_ORDER_LEFT_6(bf1, bf2, bf3, bf4, bf5, bf6)\ struct {\ R_PRAGMA(bit_order left)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ bf5;\ bf6;\ };\ R_PRAGMA(bit_order)\ } #define R_BITFIELD_BIT_ORDER_LEFT_7(bf1, bf2, bf3, bf4, bf5, bf6, bf7)\ struct {\ R_PRAGMA(bit_order left)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ bf5;\ bf6;\ bf7;\ };\ R_PRAGMA(bit_order)\ } #define R_BITFIELD_BIT_ORDER_LEFT_8(bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8)\ struct {\ R_PRAGMA(bit_order left)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ bf5;\ bf6;\ bf7;\ bf8;\ };\ R_PRAGMA(bit_order)\ } #define R_BITFIELD_BIT_ORDER_LEFT_9(bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, bf9)\ struct {\ R_PRAGMA(bit_order left)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ bf5;\ bf6;\ bf7;\ bf8;\ bf9;\ };\ R_PRAGMA(bit_order)\ } #elif defined(__GNUC__) #if defined(__RX_LITTLE_ENDIAN__) #define R_BITFIELD_BIT_ORDER_LEFT_2(bf1, bf2)\ struct {\ bf2;\ bf1;\ } #define R_BITFIELD_BIT_ORDER_LEFT_3(bf1, bf2, bf3)\ struct {\ bf3;\ bf2;\ bf1;\ } #define R_BITFIELD_BIT_ORDER_LEFT_4(bf1, bf2, bf3, bf4)\ struct {\ bf4;\ bf3;\ bf2;\ bf1;\ } #define R_BITFIELD_BIT_ORDER_LEFT_5(bf1, bf2, bf3, bf4, bf5)\ struct {\ bf5;\ bf4;\ bf3;\ bf2;\ bf1;\ } #define R_BITFIELD_BIT_ORDER_LEFT_6(bf1, bf2, bf3, bf4, bf5, bf6)\ struct {\ bf6;\ bf5;\ bf4;\ bf3;\ bf2;\ bf1;\ } #define R_BITFIELD_BIT_ORDER_LEFT_7(bf1, bf2, bf3, bf4, bf5, bf6, bf7)\ struct {\ bf7;\ bf6;\ bf5;\ bf4;\ bf3;\ bf2;\ bf1;\ } #define R_BITFIELD_BIT_ORDER_LEFT_8(bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8)\ struct {\ bf8;\ bf7;\ bf6;\ bf5;\ bf4;\ bf3;\ bf2;\ bf1;\ } #define R_BITFIELD_BIT_ORDER_LEFT_9(bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, bf9)\ struct {\ bf9;\ bf8;\ bf7;\ bf6;\ bf5;\ bf4;\ bf3;\ bf2;\ bf1;\ } #else #define R_BITFIELD_BIT_ORDER_LEFT_(bf1, bf2)\ struct {\ bf1;\ bf2;\ } #define R_BITFIELD_BIT_ORDER_LEFT_3(bf1, bf2, bf3)\ struct {\ bf1;\ bf2;\ bf3;\ } #define R_BITFIELD_BIT_ORDER_LEFT_4(bf1, bf2, bf3, bf4)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ } #define R_BITFIELD_BIT_ORDER_LEFT_5(bf1, bf2, bf3, bf4, bf5)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ bf5;\ } #define R_BITFIELD_BIT_ORDER_LEFT_6(bf1, bf2, bf3, bf4, bf5, bf6)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ bf5;\ bf6;\ } #define R_BITFIELD_BIT_ORDER_LEFT_7(bf1, bf2, bf3, bf4, bf5, bf6, bf7)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ bf5;\ bf6;\ bf7;\ } #define R_BITFIELD_BIT_ORDER_LEFT_8(bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ bf5;\ bf6;\ bf7;\ bf8;\ } #define R_BITFIELD_BIT_ORDER_LEFT_9(bf1, bf2, bf3, bf4, bf5, bf6, bf7, bf8, bf9)\ struct {\ bf1;\ bf2;\ bf3;\ bf4;\ bf5;\ bf6;\ bf7;\ bf8;\ bf9;\ } #endif #endif #if defined(__CCRX__) #define R_ATTRIB_SECTION_CHANGE(section_name) R_PRAGMA(section section_name) #define R_ATTRIB_SECTION_CHANGE_END R_PRAGMA(section) #elif defined(__GNUC__) #define R_ATTRIB_SECTION_CHANGE(section_name) __attribute__((section(#section_name))) #define R_ATTRIB_SECTION_CHANGE_END /* none */ #endif #if defined(__CCRX__) /* #define volatile volatile __evenaccess |* I guess this is a bad practice, but ... */ #elif defined(__GNUC__) #define __evenaccess /* none */ #endif /* https://gcc-renesas.com/migration-guides/rx/index.html#Compiler_predefined */ #if defined(__CCRX__) /* maybe nothing to do */ #elif defined(__GNUC__) #define __RX 1 #if defined(__RX_LITTLE_ENDIAN__) #define __LIT 1 #else #define __BIG 1 #endif #endif #endif /* SCFGCOMPILERS_H */
こんにちは。NoMaYです。今度はIAR C/C++コンパイラのユーザーズマニュアルを調べてみました。ここまでのところのCC-RXの#pragmaに相当する機能はありました。ただし、変数のセクションの変更に関しては特別な点(以下の表の赤文字)があり、恐らく、セクションの変更に関してはマクロを関数用と変数用の2つのマクロに分ける必要がありそうでした。加えて、関数のセクションの変更に関しては不明な点(同じく以下の表の赤文字)があって、少し気掛かりです。(それでも、試しに後で、今回作成しているヘッダファイルに組み込んでみようかと思います。とは言っても、IAR C/C++コンパイラはインストールしていませんので、ドキュメントだけに頼ったものになりますが、、、)C/C++ Development Guide for the Renesas RX Family (どうもFTPサーバーが重いようです)ftp.iar.se/WWWfiles/RX/webic/doc/EWRX_DevelopmentGuide.ENU.pdf
[関連リンク]Migration guide from Renesas HEW or e2 studio (どうもFTPサーバーが重いようです)ftp.iar.se/WWWfiles/RX/webic/doc/EWRX_MigratingFromRenesas.pdfProject migration toolswww.iar.com/jp/iar-embedded-workbench/project-migration/User Guides: IAR Embedded Workbench for Renesas RXwww.iar.com/support/user-guides/user-guides-iar-embedded-workbench-for-renesas-rx/
シェルティさん、こんにちは。NoMaYです。次の3連休というと明日からですね。文面から察するところ、作業中ではありますが、私の手元にあるAmazon FreeRTOSのRenesas RXのGNURXの.projectとか.cprojectとか小細工ソースとかFITソースの修正箇所情報とか、commitしておいた方が良さそうですね。今日もう少し作業を進めて、深夜にcommitしておこうかと思います。(もし寝落ちしたら、明日の朝に。^_^;)
こんにちは。NoMaYです。現在、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 Technologywww.renesas.com/ja-jp/search/keyword-search.html#genre=document&q=r01an1819r01an1819jj0350-rx-dtc-dmac2.pdf