FITのソースを見ていて気付いたCC-RXの仕様をプログラマが勘違いしている気がするコード

こんにちは。NoMaYです。

別スレッド『CC-RXもGNURXもC99仕様では_Pragmaプリプロセッサ演算子というものが使えるのですね(FITのコンパイラ対応の効率化に役立ちそうかも)』の作業中に気付いたのですが、FITの以下のようなインライン関数記述では、コンパイル時に大域最適化オプション-merge_filesを指定するようにしないと、FITのプログラマの人達が期待しているであろう(と思われる)コードは生成されないです。そんなことは百も承知かも知れませんが、、、(ちなみに、CC-RX V2では-merge_filesですが、CC-RX V1では-file_inline_path=パス名[,...]でした。)

例) r_sci_rx.c ← 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_vbatt_tx231.c ← Cファイルです

#pragma inline(r_vbatt_open_set_target_mcu)
vbatt_return_t r_vbatt_open_set_target_mcu(void)
{
    vbatt_ctrl_info_t   vbatt_set;

    vbatt_set.vbatt_ctrl.bit.func           = VBATT_ENABLE;
    vbatt_set.vbatt_ctrl.bit.lvd_level      = VBATT_CFG_DETECT_LEVEL;
    vbatt_set.vbatt_ctrl.bit.lvd_detect     = VBATT_CFG_DETECT_FUNCTION;
    vbatt_set.vbatt_int_priority            = VBATT_CFG_INT_PRIORITY;

    r_vbatt_set_io_register(&vbatt_set);

    return VBATT_SUCCESS;
}

なぜならば、CC-RXの仕様では以下の通りになっているからです。

A.2.3 関数のインライン展開を行う(ファイル間) - CS+ V6.01.00 > コンパイラ編 > クイック・ガイド > 関数 > 関数のインライン展開を行う(ファイル間)
tool-support.renesas.com/autoupdate/support/onlinehelp/ja-JP/csp/V6.01.00/CS+.chm/Compiler-CCRX.chm/Output/ccrxaac0203y.html


実際、以下のプロジェクトで試してみたところ、その通りのコードが生成されました。(当方特有の事情でCC-RX V2.03を使っています。)

プロジェクトファイル一式: issue_20180708.zip

呼び出す側のソース: TestCCRXv2_without_merge_files_option.c および TestCCRXv2_with_merge_files_option.c

#include "r_smc_entry.h"
#include "r_sci_rx_if.h"

void main(void);

uint32_t R_SCI_Version;

void main(void)
{
    R_SCI_Version = R_SCI_GetVersion();
    for (;;) {}
}

-merge_filesなしの場合に生成されたアセンブラソース: TestCCRXv2_without_merge_files_option.src


;-output=src=TestCCRXv2_without_merge_files_option.src
;-isa=rxv2
;-fpu
;-include=C:\Renesas\CS_~1\CC\CC-RX\V203~1.00\include,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRXv2_without_merge_files_option\src\smc_gen\r_bsp,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRXv2_without_merge_files_option\src\smc_gen\r_config,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRXv2_without_merge_files_option\src\smc_gen\r_gpio_rx,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRXv2_without_merge_files_option\src\smc_gen\r_gpio_rx\src,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRXv2_without_merge_files_option\src\smc_gen\r_sci_rx,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRXv2_without_merge_files_option\src\smc_gen\r_sci_rx\src,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRXv2_without_merge_files_option\src\smc_gen\r_vbatt_rx,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRXv2_without_merge_files_option\src\smc_gen\r_vbatt_rx\src,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRXv2_without_merge_files_option\src\smc_gen\r_byteq,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRXv2_without_merge_files_option\src\smc_gen\r_byteq\src,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRXv2_without_merge_files_option\src\smc_gen\general,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRXv2_without_merge_files_option\src\smc_gen\r_pincfg
;-lang=c99
;-nomessage
;-obj_path=src
;-debug
;-asm_path=src
;-nologo
;TestCCRXv2_without_merge_files_option.c

_main:
        .STACK  _main=4
        BSR _R_SCI_GetVersion
        MOV.L #_R_SCI_Version, R14
        MOV.L R1, [R14]
L11:    ; bb1
        BRA L11

-merge_filesありの場合に生成されたアセンブラソース: r_sci_rx.src


;-output=src=r_sci_rx.src
;-isa=rxv2
;-fpu
;-include=C:\Renesas\CS_~1\CC\CC-RX\V203~1.00\include,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRXv2_with_merge_files_option\src\smc_gen\r_bsp,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRXv2_with_merge_files_option\src\smc_gen\r_config,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRXv2_with_merge_files_option\src\smc_gen\r_gpio_rx,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRXv2_with_merge_files_option\src\smc_gen\r_gpio_rx\src,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRXv2_with_merge_files_option\src\smc_gen\r_sci_rx,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRXv2_with_merge_files_option\src\smc_gen\r_sci_rx\src,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRXv2_with_merge_files_option\src\smc_gen\r_vbatt_rx,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRXv2_with_merge_files_option\src\smc_gen\r_vbatt_rx\src,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRXv2_with_merge_files_option\src\smc_gen\r_byteq,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRXv2_with_merge_files_option\src\smc_gen\r_byteq\src,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRXv2_with_merge_files_option\src\smc_gen\general,C:\Renesas\e2_studio_63_rl78rxrza\workspace_e2_v630\TestCCRXv2_with_merge_files_option\src\smc_gen\r_pincfg
;-lang=c99
;-nomessage
;-obj_path=.
;-debug
;-merge_files
;-ip_optimize
;-asm_path=.
;-nologo
;../src/smc_gen/r_sci_rx/src/r_sci_rx.c
;../src/smc_gen/r_gpio_rx/src/r_gpio_rx.c
;../src/smc_gen/r_sci_rx/src/targets/rx231/r_sci_rx231.c
;../src/smc_gen/r_sci_rx/src/targets/rx231/r_sci_rx231_data.c
;../src/smc_gen/r_bsp/mcu/rx231/cpu.c
;../src/smc_gen/r_bsp/mcu/rx231/locking.c
;../src/smc_gen/r_bsp/mcu/rx231/mcu_clocks.c
;../src/smc_gen/r_bsp/mcu/rx231/mcu_init.c
;../src/smc_gen/r_bsp/mcu/rx231/mcu_interrupts.c
;../src/smc_gen/r_bsp/mcu/rx231/mcu_locks.c
;../src/TestCCRXv2_with_merge_files_option.c
;../src/smc_gen/r_pincfg/Pin.c
;../src/smc_gen/r_vbatt_rx/src/targets/vbatt/r_vbatt_rx.c
;../src/smc_gen/r_byteq/src/r_byteq.c
;../src/smc_gen/r_bsp/mcu/all/r_bsp_common.c
;../src/smc_gen/r_gpio_rx/src/targets/rx231/r_gpio_rx231.c
;../src/smc_gen/r_bsp/board/generic_rx231/dbsct.c
;../src/smc_gen/r_bsp/board/generic_rx231/hwsetup.c
;../src/smc_gen/r_bsp/board/generic_rx231/lowlvl.c
;../src/smc_gen/r_bsp/board/generic_rx231/lowsrc.c
;../src/smc_gen/r_bsp/board/generic_rx231/resetprg.c
;../src/smc_gen/r_bsp/board/generic_rx231/sbrk.c
;../src/smc_gen/r_bsp/board/generic_rx231/vecttbl.c
;../src/smc_gen/r_vbatt_rx/src/targets/vbatt/rx231/r_vbatt_rx231.c
;../src/smc_gen/general/r_cg_hardware_setup.c
;../src/smc_gen/general/r_smc_cgc.c
;../src/smc_gen/general/r_smc_cgc_user.c
;../src/smc_gen/general/r_smc_interrupt.c

_main:
        .STACK  _main=4
        MOV.L #_R_SCI_Version, R14
        MOV.L #00020001H, [R14]
L369:   ; bb1
        BRA L369

ちなみに、以下の通り-inlineは他オプションにより自動的に指定されるようにもなっています。

-size - CS+ V6.01.00 > コンパイラ編 > コマンド・リファレンス > オプション > コンパイル・オプション > 最適化オプション
tool-support.renesas.com/autoupdate/support/onlinehelp/ja-JP/csp/V6.01.00/CS+.chm/Compiler-CCRX.chm/Output/ccrx02c0501y0404.html#89331
↓となっていますが、今回は-merge_files+#pragma inlineにより-optimize=2や1や0でもインライン展開されました。


-speed - CS+ V6.01.00 > コンパイラ編 > コマンド・リファレンス > オプション > コンパイル・オプション > 最適化オプション
tool-support.renesas.com/autoupdate/support/onlinehelp/ja-JP/csp/V6.01.00/CS+.chm/Compiler-CCRX.chm/Output/ccrx02c0501y0403.html#93071
↓となっていますが、今回は-merge_files+#pragma inlineにより-optimize=1や0でもインライン展開されました。


また、以下の通り#pragma inlineはインライン展開されることを保証するものでは無いです。

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


なお、-merge_filesの仕様は以下の通りです。

-merge_files - CS+ V6.01.00 > コンパイラ編 > コマンド・リファレンス > オプション > コンパイル・オプション > 最適化オプション
tool-support.renesas.com/autoupdate/support/onlinehelp/ja-JP/csp/V6.01.00/CS+.chm/Compiler-CCRX.chm/Output/ccrx02c0501y0432.html#58958


  • こんにちは。NoMaYです。

    いつものようにCC-RXのワーニングレベルを上げてFITモジュールをコンパイルしていたら、変なコーディングを見付けてしまいました。CC-RXが以下の行でインフォメーションメッセージを出すのですが、調べてみたところ、bsp_lock_tは構造体のtypedefですので、条件コンパイルの条件には使うことが出来ないです、、、

    src/smc_gen/r_dtc_rx/src/r_dtc_rx.c

    M0520193: Zero used for undefined preprocessing identifier "bsp_lock_t"
    #if ((0 != BSP_CFG_USER_LOCKING_ENABLED) || (bsp_lock_t != BSP_CFG_USER_LOCKING_TYPE) \
          || (DTC_ENABLE != DTC_CFG_USE_DMAC_FIT_MODULE))
            /* defined(0 != BSP_CFG_USER_LOCKING_ENABLED) */
            /*  or defined(DTC_ENABLE !=DTC_CFG_USE_DMAC_FIT_MODULE) */
            /*  or defined(bsp_lock_t != BSP_CFG_USER_LOCKING_TYPE) */
            /* User has to do the locking check of DMAC by themselves. */
            ret = r_dtc_check_DMAC_locking_byUSER();
    #else



    #endif

    src/smc_gen/r_bsp/mcu/rx72n/mcu_locks.h

    typedef struct
    {
        /* The actual lock. int32_t is used because this is what the xchg() instruction takes as parameters. */
        int32_t     lock;

        /* Could add a ID for locking and unlocking. In this could protect against any function being able to unlock. */
    } bsp_lock_t;

    src/smc_gen/r_config/r_bsp_config.h

    /* If the user decides to use their own locking mechanism with FIT modules then they will need to redefine the typedef
       that is used for the locks. If the user is using a RTOS then they would likely redefine the typedef to be
       a semaphore/mutex type of their RTOS. Use the macro below to set the type that will be used for the locks.
       NOTE: If BSP_CFG_USER_LOCKING_ENABLED == 0 then this typedef is ignored.
       NOTE: Do not surround the type with parentheses '(' ')'.
    */
    #define BSP_CFG_USER_LOCKING_TYPE       bsp_lock_t

    画面コピー

     

  • こんにちは。NoMaYです。

    GNURXで出たワーニングを見て知ったのですが、このマクロ定義はポータビリティの懸念のあるものなのですね、と始めて知ったものもあります。(もっとも、怪しいマクロ定義を良く使う私が言うのも、何ですけれども、、、)

    src/smc_gen/r_dtc_rx/src/r_dtc_rx_private.h

    this use of "defined" may not be portable [-Wexpansion-to-defined]
    typedef union dtc_cra {
        uint16_t WORD;
        struct {
    #if (DTC_BIG_ENDIAN)
            uint8_t CRA_H;
            uint8_t CRA_L;
    #else /* little endian */
            uint8_t CRA_L;
            uint8_t CRA_H;
    #endif /* (DTC_BIG_ENDIAN) */
        } BYTE;
    } dtc_cra_t;

    src/smc_gen/r_dtc_rx/src/r_dtc_rx_private.h

    #define DTC_BIG_ENDIAN        (defined(__BIG) || defined(__RX_BIG_ENDIAN__))

    画面コピー