RX SmartConfiguratorのGNURX向け生成コードのBugではないかと思われる動作について

こんにちは。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 unpack
typedef 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さん
    ほや です。こんにちは。

    ひとつだけ。

    > (4) DTCを使用するコードを生成させるとビルドしたMOTファイルがRFPでエラーになる

    この対処方法について。

    .dtc_vector193 セクションの中身次第ではあるのですが、無理やりオプションを突っ込まなくてもリンカスクリプトの書き換えで対処できるのではないかと思います(動かしてみたわけではないのでテキトウに言ってますが)。

    • 初期化が必要な変数がない場合 : セクションに NOLOAD を指定する  (→ 領域だけが確保され、値はバイナリに出力されなくなる)
    • 初期値ありの変数が入る場合 : セクションのロードアドレス(ATで指定されているアドレスの方)をROMアドレスに変更する  (→ ROMアドレスの方だけがバイナリに吐かれる)

    ※ リンク先のソースを見た限りでは初期値はないので、前者の方法(NOLOAD指定)を試してみてはいかが。

  • NoMaYさん、ほやさん

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

    (1)はリンカスクリプト修正します。
    (2)(3)はBSPを修正します。
    (4)はRFPの実装なりを確認し、原因や適切な対策を探っています。何が原因でも直す方向で検討中です。

    ご報告感謝いたします。大変たすかります。

    以上です
  • シェルティ さん
    ほや です。

    (4)の件、ROMではない場所に書こうとしてRFPがエラーを吐いているのであれば、RFPとしては極めて正常な動作をしている事になります。
    (4)も直すべきはリンカスクリプト(Smart Configuratorが出力しているならその元になるリソース)の記述ではないかと考えています。

    オプションが追加できるようにするのは、それはそれで必要なのですけれど。

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

    リプライ有難う御座います。私が取った(4)の回避策は、回避策として不便には成らないようにしたかったという思惑を反映しています。リンカスクリプトの該当箇所を書き換える策は、コード生成時に元に戻ってしまうのです。(なお(B-1)のmcu_interrupt.cとvecttbl.cを書き換える策は、スマートコンフィグレータのデフォルト設定では生成済みFITモジュールは書き換えても元には戻らないこと(生成済みFITモジュールは再生成しないというデフォルト設定)を利用しています。)

    それはそれとして、ほやさんのリプライを見て、そういえば何か変なような?と思ったことがあったので、調べてみました。

    > ソースを見た限りでは初期値はない
    そもそも初期値がないのにMOTファイルにレコードが出ていたのは何故なのだろう?

    気付いたことは、__attribute__ ((section ("セクション名"))) とした場合、Cソース上で初期値無しでもGNURXコンパイラが初期値0でコードを生成していた、ということです。例えば、以下の青文字の記述部分と赤文字の記述部分で、それぞれ生成コードを比較することで違いが分かります。

    Config_DTC_ELSR18I.c

    volatile uint32_t dtc_vector193 __attribute__ ((section (".dtc_vector193")));
    volatile st_dtc_data_t dtc_transferdata_vector193[2];

    Config_DTC_ELSR18I.lst

      76                                    .comm   _dtc_transferdata_vector193,24,4
      77                                    .global _dtc_vector193
      78                                    .section    .dtc_vector193,"aw",@progbits
      79                                    .balign 4
      82                                _dtc_vector193:
      83 0000 00 00 00 00                   .zero   4

    それに対して、CC-RXでは、#pragma addressでアドレス指定した場合、Cソース上で初期値無しなら初期値無しでコードが生成されていた、ことにも気付きました。

    Config_DTC_ELSR18I.c

    #pragma address dtc_vector193=0x0003FF04U
    volatile uint32_t dtc_vector193;
    volatile st_dtc_data_t dtc_transferdata_vector193[2];

    Config_DTC_ELSR18I.lst

                                            .SECTION    B,DATA,ALIGN=4
    00000000                         _dtc_transferdata_vector193:
    00000000(00000018H)                     .blkl   6
                                            .SECTION    $ADDR_B_3FF04,DATA
                                     
    0003FF04                                .ORG        3FF04H
    0003FF04                         _dtc_vector193:
    0003FF04(00000004H)                     .blkb   4

    ちなみに別スレッド『GNURX用のCCRXmachine.hとCCRXmachine.cというソースがe2 studioフォルダにありました(内容は概ね名前から予想される通りのものでした)』で気付いたことなのですが、実はGNURXでも#pragma addressが使えます。とはいえ生成コード上は.setで定義されるだけで、領域の確保は全く行われませんので、予期せぬ領域のオーバーラップを防ぐ為に、リンカスクリプト上で領域だけは確保するようにしておく必要はあります。

    Config_DTC_ELSR18I.c

    #pragma address dtc_vector193 0x0003FF04U
    volatile uint32_t dtc_vector193;
    volatile st_dtc_data_t dtc_transferdata_vector193[2];

    Config_DTC_ELSR18I.lst

      76                                     .comm    _dtc_transferdata_vector193,24,4
      77                                    .set _dtc_vector193, 0x0003ff04

     

  • NoMaY さん
    ほや です。

    > リンカスクリプトの該当箇所を書き換える策は、コード生成時に元に戻ってしまうのです。
    そうだろうとは思いましたが...

    コード生成時に元に戻ると言う事は、やはりSmart Configuratorがスクリプトも吐いてるんですかね。

    > 予期せぬ領域のオーバーラップを防ぐ為に、リンカスクリプト上で領域だけは確保するようにしておく必要はあります。
    リンカスクリプトにKEEPが付いているのも、そういう意図だと解釈します。

    > そもそも初期値がないのにMOTファイルにレコードが出ていたのは何故なのだろう?
    KEEPで消えなくしたからか、ATで書込みアドレスをわざわざ指定してしまったためか(同じアドレスなら指定不要)、そのどちらかだと思います。

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

    先日の(4)の「そもそも初期値がないのにMOTファイルにレコードが出ていたのは何故なのだろう?」の件ですが、Windows上のMinGWというx86向けのGCCの処理系の1つで試してみたところ、MinGWでは.space擬似命令でコードが出力されていましたが、GNUのアセンブラのドキュメントによると、この擬似命令は初期値付きで領域を確保しますので、GCCというのはそういうものである、ということであるように思われます。(なおGNURXでは.zero擬似命令でコードが出力されていました。) なので、RXスマートコンフィグレータを修正する方法としては、ほやさんが指摘されたように、リンカスクリプトでNOLOAD指定をするように修正するのが良さそうな気がします。

    ソース上の記述

    volatile uint32_t dtc_vector193 __attribute__ ((section (".dtc_vector193")));

    gcc (MinGW.org GCC-6.3.0-1)でのリストファイル

      40                        .globl  _dtc_vector193
      41 001e 9090              .section    .dtc_vector193,"w"
      42                        .align 4
      43                    _dtc_vector193:
      44 0000 00000000          .space 4

    rx-elf-gcc (GNURX 2018q3 4.8.4.201803)でのリストファイル

      77                        .global _dtc_vector193
      78                        .section    .dtc_vector193,"aw",@progbits
      79                        .balign 4
      82                    _dtc_vector193:
      83 0000 00 00 00 00       .zero   4

     以下、GCCのアセンブラのドキュメントの画面コピーです。

    sourceware.org/binutils/docs/as/Space.html#Space

    .space size , fill
    This directive emits size bytes, each of value fill. Both size and fill are absolute expressions. If the comma and fill are omitted, fill is assumed to be zero.



    sourceware.org/binutils/docs/as/Zero.html#Zero

    .zero size
    This directive emits size 0-valued bytes. size must be an absolute expression.



    ちなみに、GCCのドキュメントを過去に遡って調べたところ、gcc-4.3.6とgcc-4.4.7の間で__attribute__ ((section ("セクション名")))に関して以下の仕様の拡張があったことに気付きましたが、その仕組みは、C言語上は初期値無し変数も結局は0という初期値を持つので初期値無しで領域を確保するのも初期値0で領域を確保するもの結局は区別が付かない、という発想で上に書いたようになっているのかも知れません。

    __attribute__ ((section ("セクション名")))についてのGCCのドキュメントの記載

    gcc-4.3.6以前: 初期値付きグローバル変数にのみ適用出来る

    You may only use the section attribute with a fully initialized global definition


    gcc-4.4.7以後: 初期値付きグローバル変数だけでなく初期値無しグローバル変数にも適用出来る

    You may use the section attribute with initialized or uninitialized global variables


    以下、GCCのドキュメントの画面コピーです。(赤枠は私によるものです。)

    gcc-4.3.6
    gcc.gnu.org/onlinedocs/gcc-4.3.6/gcc/Variable-Attributes.html#index-g_t_0040code_007bsection_007d-variable-attribute-2216


    gcc-4.4.7
    gcc.gnu.org/onlinedocs/gcc-4.4.7/gcc/Variable-Attributes.html#index-g_t_0040code_007bsection_007d-variable-attribute-2316


     

  • こんにちは。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;
    #endif
    const 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;
    #endif
    const 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
        .dtc_vector26 0x3ff04 (NOLOAD) : AT(0x3ff04)
        {
            KEEP(*(.dtc_vector26))
        } >RAM

    なお添付したプロジェクトは、以下の画面コピーのようになっていますが、動作させることを目的としたものではないです。


     

  • NoMaYさん

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

    お手数おかけしてすみません。また、レポートありがとうございます。
    早速ツール開発とBSP開発に情報展開しました。見解を集めて返信いたします。

    以上です
  • こんにちは。NoMaYです。

    別の作業をしていて、ふと気付いたのですが、このスレッドで以前(e2 studio v7.3.0の頃)に「Objcopy→Generalの設定で任意のオプションを追加することが出来れば良かったのですが、、、」と書いたのですが、今(少なくともe2 studio v7.6.0)では出来るようになっていますね、、、

    以前(e2 studio v7.3.0)の画面コピー


    現在(e2 studio v7.6.0)の画面コピー

     

  • NoMaYさん

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

    Objcopyの任意オプションの書込みを見て、先に改善要望いただいていたところに回答していないことに気付きました。申し訳ありません。

    対策進捗の最新状況を開発チームに確認しました。
    (1)は次のBSP(11月頃リリース予定)で修正されます。
    (2)(3)は優先的に直し方を検討中です。
    (4)~(7)は直し方を検討中です。

    ●バグ

    (1) MDE, OFS0, OFS1, OSIS1, OSIS2, OSIS3, OSIS4の配置アドレスが間違っている
    (2) 変数が0番地から配置されている(変数のアドレスがNULLと区別出来ない変数が出来てしまっている)
    (3) DTCベクタが正しいアドレスに配置されない(正しいアドレスに領域が確保されない)

    ●改善事項

    (4) 0番地に変数が配置されないようにする為の領域サイズをGNURXとCC-RXで合わせた方が良いと思う
    (5) もし特別な主張がなければスタックの配置もGNURXとCC-RXで合わせた方が良いと思う
    (6) リンカスクリプトのインデントが崩れている箇所は綺麗にした方が良いと思う
    (7) リンカスクリプトで一部のシンボルだけダブルクォーテーションで囲まれているものがあるが不要だと思う

    以上です