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の別スレッドで使用していたものです。)


Parents
  • こんにちは。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開発に情報展開しました。見解を集めて返信いたします。

    以上です
Reply
  • NoMaYさん

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

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

    以上です
Children
  • 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) リンカスクリプトで一部のシンボルだけダブルクォーテーションで囲まれているものがあるが不要だと思う

    以上です