こんにちは。NoMaYです。RXスマートコンフィグレータ(V2.0.0)とGNURX 2018q3(4.8.4.201803)でプログラムを作成しようとして気付いたものです。(RXスマートコンフィグレータに起因するものだけで無くe2 studioやGNURXに起因するものもあります。) (なおCC-RX向け生成コードでも発生するものはこちらのスレッドにあります。)プロジェクトのファイル一式issue_20190413.zip(1) RX65NのROM大版ではRAMは0~0x3FFFFと0x800000~0x85FFFFにあるがリンカスクリプト上は0~0x9FFFFの扱いである(2) GNURXでは未サポートの#pragamディレクティブを含んでいるソースがある(3) グループ割り込み関数とバスエラー割り込み関数に__attribute__ ((interrupt))が付いていない(4) DTCを使用するコードを生成させるとビルドしたMOTファイルがRFPでエラーになる以下、その詳細と私が取った回避策です。(1) RX65NのROM大版ではRAMは0~0x3FFFFと0x800000~0x85FFFFにあるがリンカスクリプト上は0~0x9FFFFの扱いであるもともとはGR-ROSEの開発者さんの指摘なのですが、生成されたリンカスクリプトは以下の通りです。src/linker_script.ld
MEMORY{ RAM : ORIGIN = 0x0, LENGTH = 655360 ROM : ORIGIN = 0xFFE00000, LENGTH = 2097152 OFS : ORIGIN = 0xFE7F5D00, LENGTH = 256}
回避策は以下のように修正することです。(これはGR-ROSEの開発者さんが指摘していた回避策です。)
MEMORY{ RAM : ORIGIN = 0x0, LENGTH = 262144 RAMHI : ORIGIN = 0x800000, LENGTH = 393216 ROM : ORIGIN = 0xFFE00000, LENGTH = 2097152 OFS : ORIGIN = 0xFE7F5D00, LENGTH = 256}
(2) GNURXでは未サポートの#pragamディレクティブを含んでいるソースがあるGNURXでは以下の4つの#pragamディレクティブは無視されますが、#pragma bit_order leftが無視された状況では以下のビットフィールドの並び順はビッグエンディアンでの並び順であり、リトルエンディアンでは逆順にするのが正しいです。src/smc_gen/r_bsp/board/generic_rx65n/hwsetup.c
#pragma bit_order left#pragma unpacktypedef struct bsp_bsc { union { uint32_t u_long; struct { uint32_t prerr:1; uint32_t :1; uint32_t rpstop:1; uint32_t :10; uint32_t pr5sel:3; uint32_t :1; uint32_t pr4sel:3; uint32_t :1; uint32_t pr3sel:3; uint32_t :1; uint32_t pr2sel:3; uint32_t :1; uint32_t pr1sel:3; } bit; } ebmapcr;} st_bsp_bsc_t;#pragma bit_order#pragma packoption
回避策は以下の通りです。(なお、CC-RX/GNURX/ICCRX共通化BSPがリリースされれば修正される筈です。)(A) BSCユニットのEBMAPCRレジスタにアクセスしなければ放置する(そもそもROM 2MB版でしかアクセスされない)(B) アクセスするのであればGNURX向けiodefine.hから切り貼りして以下のように修正する
#pragma pack(4)typedef struct bsp_bsc { union { uint32_t u_long; struct {#ifdef __RX_LITTLE_ENDIAN__ uint32_t pr1sel:3; uint32_t :1; uint32_t pr2sel:3; uint32_t :1; uint32_t pr3sel:3; uint32_t :1; uint32_t pr4sel:3; uint32_t :1; uint32_t pr5sel:3; uint32_t :10; uint32_t rpstop:1; uint32_t :1; uint32_t prerr:1;#else uint32_t prerr:1; uint32_t :1; uint32_t rpstop:1; uint32_t :10; uint32_t pr5sel:3; uint32_t :1; uint32_t pr4sel:3; uint32_t :1; uint32_t pr3sel:3; uint32_t :1; uint32_t pr2sel:3; uint32_t :1; uint32_t pr1sel:3;#endif } bit; } ebmapcr;} st_bsp_bsc_t;#pragma pack()
(3) グループ割り込み関数とバスエラー割り込み関数に__attribute__ ((interrupt))が付いていないヘッダファイル上では、これらの関数に__attribute__ ((interrupt))が付いていますが、インクルードするのを忘れたのだろうと思います。src/smc_gen/r_bsp/mcu/rx65n/mcu_interrupt.c
void group_bl0_handler_isr (void){略}
void group_bl1_handler_isr (void){略}
void group_bl2_handler_isr (void){略}
void group_al0_handler_isr (void){略}
void group_al1_handler_isr (void){略}
src/smc_gen/r_bsp/board/generic_rx65n/vecttbl.c
void bus_error_isr (void){略}
src/smc_gen/general/r_cg_interrupt_handlers.h
/* BSC BUSERR */void bus_error_isr(void) __attribute__ ((interrupt));略/* ICU GROUPBL2 */void group_bl2_handler_isr(void) __attribute__ ((interrupt));/* ICU GROUPBL0 */void group_bl0_handler_isr(void) __attribute__ ((interrupt));/* ICU GROUPBL1 */void group_bl1_handler_isr(void) __attribute__ ((interrupt));/* ICU GROUPAL0 */void group_al0_handler_isr(void) __attribute__ ((interrupt));/* ICU GROUPAL1 */void group_al1_handler_isr(void) __attribute__ ((interrupt));
回避策は以下の通りです。(なお、CC-RX/GNURX/ICCRX共通化BSPがリリースされれば修正される筈です。)(A) グループ割り込み関数とバスエラー割り込み関数を使わなければ放置する(B) 使うのであれば以下の何れかの策を取る(B-1) mcu_interrupt.cとvecttbl.cに以下を追加する
#include "platform.h"#include "r_cg_interrupt_handlers.h"
(B-2) r_bsp_config.hに以下を追加する
#include "r_cg_interrupt_handlers.h"
(4) DTCを使用するコードを生成させるとビルドしたMOTファイルがRFPでエラーになるDTCを使用すると、以下のように、ソースが生成されて、リンカスクリプトにセクションが追加されて、RAM上に初期値が割り当てられますが、それがrx-elf-objcopyによりMOTファイルにレコードとして出力され、そのレコードが最近のRFPではエラーになります。src/smc_gen/Config_DTC_ELSR18I/Config_DTC_ELSR18I.c
volatile uint32_t dtc_vector193 __attribute__ ((section (".dtc_vector193")));
src/linker_script.ld
.dtc_vector193 0x3ff04 : AT(0x3ff04) { KEEP(*(.dtc_vector193)) } >RAM
MAPファイル
.dtc_vector193 0x0003ff04 0x4 *(.dtc_vector193) .dtc_vector193 0x0003ff04 0x4 ./src/smc_gen/Config_DTC_ELSR18I/Config_DTC_ELSR18I.o 0x0003ff04 _dtc_vector193
MOTファイル
S3090003FF0400000000F0
RFP V3.05.01のエラーの画面コピー回避策は以下の画面コピーのようにプロジェクトのプロパティでrx-elf-objcopyのオプションを変更してしまうことです。(今のところは素朴にObjcopyのオプションを追加する方法は無さそうです。以下の画面コピーのObjcopy→Generalの設定で任意のオプションを追加することが出来れば良かったのですが、、、)エキスパート設定のコマンド行パターンに -R .dtc_vector* を追加する任意のオプションを追加することが出来ると良かったのですが、、、ちなみに上記の(2)と(3)はワーニングレベルを上げると、そのものズバリ(赤枠)、あるいは当たらずしも遠からず(橙枠)、で以下の画面コピーのようにGNURXコンパイラにより検出されていました。(なお以下のワーニング設定はAmazon FreeRTOSの別スレッドで使用していたものです。)
こんにちは。NoMaYです。e2 studio 7.5.0+RXスマートコンフィグレータplugin 7.5.0+GNURX 2019q2(4.8.4.201902)で作業していてバグと改善事項に気付きました。以下の(1)はR_BSPモジュールのバグ、続く(2)と(3)はRXスマートコンフィグレータのバグ、改善事項はRXスマートコンフィグレータに関するものです。バグ再現と回避策案のプロジェクトのファイル一式issue_20191003.zip 821KB●バグ(1) MDE, OFS0, OFS1, OSIS1, OSIS2, OSIS3, OSIS4の配置アドレスが間違っている(2) 変数が0番地から配置されている(変数のアドレスがNULLと区別出来ない変数が出来てしまっている)(3) DTCベクタが正しいアドレスに配置されない(正しいアドレスに領域が確保されない)●改善事項(4) 0番地に変数が配置されないようにする為の領域サイズをGNURXとCC-RXで合わせた方が良いと思う(5) もし特別な主張がなければスタックの配置もGNURXとCC-RXで合わせた方が良いと思う(6) リンカスクリプトのインデントが崩れている箇所は綺麗にした方が良いと思う(7) リンカスクリプトで一部のシンボルだけダブルクォーテーションで囲まれているものがあるが不要だと思う以下、詳細です。●バグ(1) MDE, OFS0, OFS1, OSIS1, OSIS2, OSIS3, OSIS4の配置アドレスが間違っているMAPファイルを見ると以下のようになっていましたが、期待される配置アドレスではありません。現状)
.ofs1 0xfe7f5d00 0xc *(.ofs1) .ofs1 0xfe7f5d00 0xc ./src/smc_gen/r_bsp/mcu/rx65n/vecttbl.o 0xfe7f5d00 ___OFS1reg 0xfe7f5d04 ___OFS0reg 0xfe7f5d08 ___MDEreg
.ofs6 0xfe7f5d50 0x10 *(.ofs6) .ofs6 0xfe7f5d50 0x10 ./src/smc_gen/r_bsp/mcu/rx65n/vecttbl.o 0xfe7f5d50 ___OSIS4reg 0xfe7f5d54 ___OSIS3reg 0xfe7f5d58 ___OSIS2reg 0xfe7f5d5c ___OSIS1reg
期待値)
.ofs1 0xfe7f5d00 0xc *(.ofs1) .ofs1 0xfe7f5d00 0xc ./src/smc_gen/r_bsp/mcu/rx65n/vecttbl.o 0xfe7f5d00 ___MDEreg 0xfe7f5d04 ___OFS0reg 0xfe7f5d08 ___OFS1reg
.ofs6 0xfe7f5d50 0x10 *(.ofs6) .ofs6 0xfe7f5d50 0x10 ./src/smc_gen/r_bsp/mcu/rx65n/vecttbl.o 0xfe7f5d50 ___OSIS1reg 0xfe7f5d54 ___OSIS2reg 0xfe7f5d58 ___OSIS3reg 0xfe7f5d5c ___OSIS4reg
原因はR_BSPモジュールのvecttbl.cの以下の部分です。変数がアドレス昇順に配置される保障は無く、実際にはGNURXでは降順に配置されてしまったことによります。(実は、Amazon FreeRTOSの作業時に、この記述を既に見ていたのですが、そのことにまで気付きませんでした。)src/smc_gen/r_bsp/mcu/rx65n/vecttbl.c
#elif defined(__GNUC__)const uint32_t __MDEreg __attribute__ ((section(".ofs1"))) = (BSP_PRV_MDE_VALUE & BSP_PRV_BANK_MODE_VALUE);const uint32_t __OFS0reg __attribute__ ((section(".ofs1"))) = BSP_CFG_OFS0_REG_VALUE;const uint32_t __OFS1reg __attribute__ ((section(".ofs1"))) = BSP_CFG_OFS1_REG_VALUE;const uint32_t __TMINFreg __attribute__ ((section(".ofs2"))) = 0xffffffff;#if defined(BSP_MCU_RX65N_2MB)const uint32_t __BANKSELreg __attribute__ ((section(".ofs3"))) = BSP_PRV_START_BANK_VALUE;#endifconst uint32_t __SPCCreg __attribute__ ((section(".ofs4"))) = 0xffffffff;const uint32_t __TMEFreg __attribute__ ((section(".ofs5"))) = BSP_CFG_TRUSTED_MODE_FUNCTION;const uint32_t __OSIS1reg __attribute__ ((section(".ofs6"))) = BSP_CFG_ID_CODE_LONG_1;const uint32_t __OSIS2reg __attribute__ ((section(".ofs6"))) = BSP_CFG_ID_CODE_LONG_2;const uint32_t __OSIS3reg __attribute__ ((section(".ofs6"))) = BSP_CFG_ID_CODE_LONG_3;const uint32_t __OSIS4reg __attribute__ ((section(".ofs6"))) = BSP_CFG_ID_CODE_LONG_4;const uint32_t __FAWreg __attribute__ ((section(".ofs7"))) = BSP_CFG_FAW_REG_VALUE;const uint32_t __ROMCODEreg __attribute__ ((section(".ofs8"))) = BSP_CFG_ROMCODE_REG_VALUE;
回避策案は以下の通りです。src/smc_gen/r_bsp/mcu/rx65n/vecttbl.c
#elif defined(__GNUC__)typedef struct { uint32_t __MDEreg; uint32_t __OFS0reg; uint32_t __OFS1reg;} sec_ofs1;typedef struct { uint32_t __OSIS1reg; uint32_t __OSIS2reg; uint32_t __OSIS3reg; uint32_t __OSIS4reg;} sec_ofs6;const sec_ofs1 __sec_ofs1 __attribute__ ((section(".ofs1"))) = {/* uint32_t __MDEreg = */ (BSP_PRV_MDE_VALUE & BSP_PRV_BANK_MODE_VALUE),/* uint32_t __OFS0reg = */ BSP_CFG_OFS0_REG_VALUE,/* uint32_t __OFS1reg = */ BSP_CFG_OFS1_REG_VALUE};const uint32_t __TMINFreg __attribute__ ((section(".ofs2"))) = 0xffffffff;#if defined(BSP_MCU_RX65N_2MB)const uint32_t __BANKSELreg __attribute__ ((section(".ofs3"))) = BSP_PRV_START_BANK_VALUE;#endifconst uint32_t __SPCCreg __attribute__ ((section(".ofs4"))) = 0xffffffff;const uint32_t __TMEFreg __attribute__ ((section(".ofs5"))) = BSP_CFG_TRUSTED_MODE_FUNCTION;const sec_ofs6 __sec_ofs6 __attribute__ ((section(".ofs6"))) = {/* uint32_t __OSIS1reg = */ BSP_CFG_ID_CODE_LONG_1,/* uint32_t __OSIS2reg = */ BSP_CFG_ID_CODE_LONG_2,/* uint32_t __OSIS3reg = */ BSP_CFG_ID_CODE_LONG_3,/* uint32_t __OSIS4reg = */ BSP_CFG_ID_CODE_LONG_4};const uint32_t __FAWreg __attribute__ ((section(".ofs7"))) = BSP_CFG_FAW_REG_VALUE;const uint32_t __ROMCODEreg __attribute__ ((section(".ofs8"))) = BSP_CFG_ROMCODE_REG_VALUE;
(2) 変数が0番地から配置されている(変数のアドレスがNULLと区別出来ない変数が出来てしまっている)MAPファイルを見ると以下のようになっていましたが、変数ch1_ctrlが0番地に配置されてしまっています。この変数のアドレスはNULLと区別出来ないのですが、その為にR_SCI_RXモジュールが変数ch1_ctrlを正しく認識出来なくなってしまいました。
.data 0x00000000 0x2c load address 0xffe03818 0x00000000 _data = . *(.data) *(.data.*) .data.ch1_ctrl 0x00000000 0x20 ./src/smc_gen/r_sci_rx/src/targets/rx65n/r_sci_rx65n_data.o 0x00000000 _ch1_ctrl
原因はリンカスクリプトの以下の記述です。0番地に変数が配置されないようにする為の領域の記述位置が間違っていました。誤)
.tors : { 略 _mdata = .; } > ROM .data : AT(_mdata) { 略 } > RAM .gcc_exc : { 略 } > RAM .bss : { 略 } > RAM .ofs1 0xFE7F5D00: AT(0xFE7F5D00) { KEEP(*(.ofs1)) } > OFS 略 .ofs8 0xFE7F5D70: AT(0xFE7F5D70) { KEEP(*(.ofs8)) } > OFS .r_bsp_NULL : { . += 0x100; "_r_bsp_NULL_end" = .; } >RAM 略
正)
.tors : { 略 _mdata = .; } > ROM .r_bsp_NULL : { . += 0x100; "_r_bsp_NULL_end" = .; } >RAM .data : AT(_mdata) { 略 } > RAM .gcc_exc : { 略 } > RAM .bss : { 略 } > RAM .ofs1 0xFE7F5D00: AT(0xFE7F5D00) { KEEP(*(.ofs1)) } > OFS 略 .ofs8 0xFE7F5D70: AT(0xFE7F5D70) { KEEP(*(.ofs8)) } > OFS 略
(3) DTCベクタが正しいアドレスに配置されない(正しいアドレスに領域が確保されない)このスレッドで以前に指摘したバグが修正されたのは良いのですが、別のバグが追加されていました。アドレスが間違っています。現状)
.dtc_vector26 0x00001eb4 0x4 load address 0xffe056cc *(.dtc_vector26) .dtc_vector26 0x00001eb4 0x4 ./src/smc_gen/Config_DTC_ELSR18I/Config_DTC_ELSR18I.o 0x00001eb4 _dtc_vector26
.dtc_vector26 0x0003ff04 0x4 *(.dtc_vector26) .dtc_vector26 0x0003ff04 0x4 ./src/smc_gen/Config_DTC_ELSR18I/Config_DTC_ELSR18I.o 0x0003ff04 _dtc_vector26
原因はリンカスクリプトの以下の記述です。アドレス指定が無くなっています。誤)
.dtc_vector26 (NOLOAD) : { KEEP(*(.dtc_vector26)) } >RAM}
.dtc_vector26 0x3ff04 (NOLOAD) : AT(0x3ff04) { KEEP(*(.dtc_vector26)) } >RAM
●改善事項(4) 0番地に変数が配置されないようにする為の領域サイズをGNURXとCC-RXで合わせた方が良いと思うAmazon FreeRTOSの作業時に、0番地に変数が配置されないようにする為ではなく、プログラムの誤りによる0番地付近の変数(というかスタック領域)破壊への堅牢さ向上を目的として、CC-RX版もGNURX版も256バイト空けるようにしたのですが、その値が使われています。現状、RXスマートコンフィグレータでコード生成した時、CC-RX版では4バイトのみですので、GNURX版も4バイトで良いのではと思います。現状)
.r_bsp_NULL : { . += 0x100; "_r_bsp_NULL_end" = .; } >RAM
望ましいのではと私が思うもの)
.r_bsp_NULL : { . += 0x4; _r_bsp_NULL_end = .; } >RAM
(5) もし特別な主張がなければスタックの配置もGNURXとCC-RXで合わせた方が良いと思う以前のRXスマートコンフィグレータでは(というかe2 studioが生成した素のプロジェクトも)、意図的にCC-RXと合わせたのかどうか分かなないですが、スタックがCC-RXと同様にRAMの0番地の方にありました。今回、それがRAMの上位番地側に移っていますが、もし特別な主張がなければスタックの配置もGNURXとCC-RXで合わせた方が良いのではと思います。[補足]投稿する直前になって気付いたのですが、CC-RXとGNURXでは、IスタックとUスタックの配置(上下)が逆になってますね。CC-RXではUスタックが0番地側、GNURXではIスタックが0番地側、ですね。以前に、以下のスレッドでMPUについて調べた時に、Uスタックが0番地側にある方(CC-RX)が良さそうな気がしましたので、これもCC-RXに合わせた方が良さそうな気がしてきました。RX631スタック領域等を保護するには?japan.renesasrulz.com/cafe_rene/f/forum5/4648/rx631/25141#25141(6) リンカスクリプトのインデントが崩れている箇所は綺麗にした方が良いと思う(7) リンカスクリプトで一部のシンボルだけダブルクォーテーションで囲まれているものがあるが不要だと思うなぜインデントが崩れていたり、なぜ一部のシンボルだけダブルクォーテーションで囲まれていたり、というようになっているか分からないですが、RXスマートコンフィグレータがバージョンアップされた時に.c/.hの無用な空白文字が取れていたり、#defineで括弧の有無が変わっていたり、とかしていますので、これも綺麗にした方が良いのではと思います。現状)
.exvectors 0xFFFFFF80: AT(0xFFFFFF80) { "_exvectors_start" = .; KEEP(*(.exvectors)) "_exvectors_end" = .; } >ROM
.r_bsp_NULL : { . += 0x100; "_r_bsp_NULL_end" = .; } >RAM.r_bsp_istack BLOCK(0x4) (NOLOAD) : { KEEP(*(.r_bsp_istack)) } >RAM.istack : { "_istack" = .; } >RAM.r_bsp_ustack BLOCK(0x4) (NOLOAD) : { KEEP(*(.r_bsp_ustack)) } >RAM.ustack : { "_ustack" = .; } >RAM
.dtc_vector26 (NOLOAD) : { KEEP(*(.dtc_vector26)) } >RAM
望ましいのではと私が思うもの) (投稿する直前になって気付いたのですがUスタックが0番地側にある方が良いかも知れません)
.exvectors 0xFFFFFF80: AT(0xFFFFFF80) { _exvectors_start = .; KEEP(*(.exvectors)) _exvectors_end = .; } >ROM
.r_bsp_NULL : { . += 0x4; _r_bsp_NULL_end = .; } >RAM .r_bsp_istack BLOCK(0x4) (NOLOAD) : { KEEP(*(.r_bsp_istack)) } >RAM .istack : { _istack = .; } >RAM .r_bsp_ustack BLOCK(0x4) (NOLOAD) : { KEEP(*(.r_bsp_ustack)) } >RAM .ustack : { _ustack = .; } >RAM
なお添付したプロジェクトは、以下の画面コピーのようになっていますが、動作させることを目的としたものではないです。