Amazon AWSのFreeRTOS Kernel Developer GuideのサンプルコードをRenesas RX SimulatorのDebug Consoleで試せるようにしてみた

こんにちは。NoMaYです。

別スレッドで、AWSドキュメントサイト内にFreeRTOS kernelの開発者ガイドの日本語版が載っていることに気付いたのですが、その中に含まれているCコード例をルネサスRXシミュレータで試せたら面白そうだと思い、やってみました。まずはCC-RX(CS+/e2 studio)版です。後日GNURX(e2 studio)版もやろうと思います。以下、プロジェクトのファイル一式です。(CS+ V8.01+CC-RX V2.03でビルド)(e2 studio用.project/.cproject等を同梱(zipファイルをe2 studioに直接インポート可能))

sim_rx65n_freertos_ccrx_c_csplus_20190526.zip

やったこと(主なもの)

(1) FreeRTOS kernelがルネサスRXシミュレータの未対応機能を使っていたので無理矢理に対応機能のみ使うように小細工
(2) Full DemoからルネサスRXシミュレータの未対応機能を使っている項目を除外
(3) ルネサスRXシミュレータではBSPモジュール内で無限ループしてしまう点を回避
(4) 開発者ガイドのCコード例で使われているvPrintString()をDebug Consoleへ出力するように作成
(5) Full Demo/Simple Blinky Demo/Cコード例でvAssertCalled()呼び出し時にDebug Consoleへメッセージを出力
(6) Full Demo/Simple Blinky DemoでLEDのOn/OffのタイミングでDebug ConsoleへOn/Offのメッセージを出力
(7) 開発者ガイドのCコード例が動くようにルネサスRXシミュレータの起動設定を変更(私の個人的な好みを含む)
(8) 開発者ガイドのCコード例をビルドする時には不要なデモソースをビルドから除外したプロジェクトを作成(CS+のみ)
(9) 開発者ガイドのCコード例をビルドするプロジェクトではコンパイル時の最適化レベルを0に変更(CS+のみ)

以下、FreeRTOS kernelの開発者ガイドのCコード例をルネサスRXシミュレータで動かした時の画面コピーです。(上記の(8)のプロジェクトです。)

FreeRTOS kernelの開発者ガイドではFreeRTOS Windowsシミュレータで実行
docs.aws.amazon.com/ja_jp/freertos-kernel/latest/dg/task-management.html


ルネサスRXシミュレータで実行


ビルドした時のビルド設定とビルド結果


zipファイルには、開発者ガイドのCコード例をビルドするプロジェクト(CS+のみ)の他に、別スレッドに投稿した、RX65N TBボードで動く(といってもデバッグ中ではありますが)Full Demo/Simple Blinky Demoをビルドするプロジェクトも含まれています。(上記の(2)で除外している項目はありますが。) 以下、それらの画面コピーです。

CS+


e2 studio

Parents
  • こんにちは。NoMaYです。#3連投の1つ目です。

    今度はRenesas RL78 Simulatorでやってみました。残念ながらデバッグコンソール機能はありませんので、CS+ではPrintf Action Event機能を、e2 studioではDynamic Printf機能を、それぞれ使用しました。また、Simulator GUIにはLEDやButtonなどのGUI部品を並べたパネルを作成する機能がありますので、コード生成機能+FreeRTOSで割り込みを扱う簡単なプログラムを作成して、動作確認してみました。(今回は実機での確認をしてません。)

    以下、プロジェクトのファイル一式です。(CC-RL版はCS+ V8.01/e2 stuiod v7.40+CC-RX V1.02でビルド(e2 studio用.project/.cproject等を同梱))(GNURL78版はe2 studio v7.40+GNURL78 2019q2(4.9.2.201902)でビルド)(共にzipファイルをe2 studioに直接インポート可能) プロジェクト構造は極力RX版と同じにしてみました。

    sim_rl78_freertos_ccrl_c_csplus_20190612.zip    580KB
    sim_rl78_freertos_gnurl78_c_e2v740_20190612.zip    677KB

    以下、Printf Action Eventでの実行結果、Dynamic Printfでの実行結果、Simulator GUIでLEDとButtonを配置したパネル、の画面コピーです。







    今回のプロジェクトのベースは、別スレッド『FreeRTOSをFITやCG(や追々PDG2でも?)と一緒に使うサンプルプログラムをCSplusでビルド出来るプロジェクトにしてみた』のCC-RL版GNURL78版ですが、以下の小細工を追加しています。(なお、長時間運転の件は1年放置してしまっています。すみません、、、)

    (1) コード生成されたr_cg_macrodriver.hとFreeRTOSが使用するstdint.hとのint8_t/uint8_t等のtypedefの衝突の回避(CC-RL)
    (2) コード生成されたr_cg_vector_table.cにFreeRTOSのvPortTickISRとvPortYieldをスクリプトで自動ベクタ登録する(GNURL78)

    また、作業していて、以下の点には留意しておいた方が良さそうな気がしました。

    (3) FreeRTOSのstream_buffer.cでCC-RLの「偶数アライメントのオブジェクトを指すポインタが奇数番地を保持しています」が出る
    (4) FreeRTOSのGNURL78版では割り込み用スタックが使用されるが多重割り込みに対応していない(他方CC-RL版では使用されない)

    以下、その詳細です。

    (1) コード生成されたr_cg_macrodriver.hとFreeRTOSが使用するstdint.hとのint8_t/uint8_t等のtypedefの衝突の回避(CC-RL)

    幸い、FreeRTOSが使用するint8_t/uint8_t等のtypedefはr_cg_macrodriver.hに記述されているもので足りるようでしたので、以下のように小細工しました。(赤文字箇所)

    src/frtos_startup/freertos_start.h

    #include "r_cg_macrodriver.h"
    #include "r_cg_userdefine.h"
    #if defined(__CCRL__)
    #define _STDINT_H
    #endif
    #include "FreeRTOS.h"
    #include "task.h"
    #include "semphr.h"
    #include "queue.h"
    #include "croutine.h"
    #include "timers.h"
    #include "event_groups.h"

    (2) コード生成されたr_cg_vector_table.cにFreeRTOSのvPortTickISRとvPortYieldをスクリプトで自動ベクタ登録する(GNURL78)

    今回、r_cg_vector_table.jsというスクリプトを作成して、ビルド時に自動的に実行されるようにしました。このスクリプトでr_cg_vector_table.cを以下のように書き換えます。FreeRTOSのvPortTickISRとvPortYieldの他にも利用出来るよう、ちょっと大げさに書き換えることにしました。

    src/r_cg_vector_table.c

    自動書き換え前

    #include "r_cg_macrodriver.h"
    #include "r_cg_userdefine.h"

    ...略...

    #define VECT_SECT          __attribute__ ((section (".vects")))
    const void *Vectors[] VECT_SECT  = {
        // Address 0x4
        R_Dummy,
        ...略...
        // Address 0x7E
        R_Dummy,
    };

    自動書き換え後

    #include "r_cg_macrodriver.h"
    #include "r_cg_userdefine.h"
    #include "r_cg_vector_table.h"

    ...略...
    #define VECT_SECT          __attribute__ ((section (".vects")))
    const void *Vectors[] VECT_SECT  = {
        // Address 0x4
        R_Vector_0x4,
        ...略...
        // Address 0x7E
        R_Vector_0x7E,
    };

    そして、新規追加したr_cg_vector_table.hで以下のように任意のベクタを登録出来るようにしてみました。

    src/r_cg_vector_table.h

    /* Defines for user */

    /*
     * INT_IT (0x38 or 0x3C)
     */
    #if INTIT_vect == 0x38

    #define R_Vector_0x38 vPortTickISR

    #elif INTIT_vect == 0x3C

    #define R_Vector_0x3C vPortTickISR

    #else

    #error Neither vector 0x38 nor vector 0x3C is available for the tick interrupt.

    #endif

    /*
     * INT_BRK_I (0x7E)
     */
    #define R_Vector_0x7E vPortYield

    void vPortTickISR(void) __attribute__ ((interrupt));
    void vPortYield(void) __attribute__ ((interrupt));

    /* Defines for default */

    #ifndef R_Vector_0x4
    #define R_Vector_0x4  R_Dummy
    #endif
    ...略...
    #ifndef R_Vector_0x7E
    #define R_Vector_0x7E R_Dummy
    #endif

    (3) FreeRTOSのstream_buffer.cでCC-RLの「偶数アライメントのオブジェクトを指すポインタが奇数番地を保持しています」が出る

    CC-RLでコンパイルすると以下のワーニングが出ます。(GNURL78では出ませんがチェックしていないからです。) もしstream_buffer.cの機能を使用するのであれば、問題無いかどうか確認してから使用する必要があります。(今回、ちょっと気力不足で、私はFreeRTOSのソースを調べていないです。)

    src\FreeRTOS\Source\stream_buffer.c(262):W0523082:偶数アライメントのオブジェクトを指すポインタが奇数番地を保持しています。
    src\FreeRTOS\Source\stream_buffer.c(275):W0523082:偶数アライメントのオブジェクトを指すポインタが奇数番地を保持しています。

    (4) FreeRTOSのGNURL78版では割り込み用スタックが使用されるが多重割り込みに対応していない(他方CC-RL版では使用されない)

    もともとFreeRTOS 10.2.1のソースにCC-RL版はありませんので正確にはCC-RL版のベースにしたIAR版では使用されていない、ということなのですが、それに対してGNURL78版では以下のように割り込み用スタックへの切り替えが行われています。FreeRTOSカーネル自体は多重割り込み対応だろうとは思っていますが、以下の部分が多重割り込みでは誤動作する(多重割り込みでスタックポインタが割り込み用スタックの初期値に戻ってしまう)ので、もしGNURL78版でFreeRTOS APIを多重割り込み内から呼び出すようなことをしたければ改造が必要です。

    src/FreeRTOS/Source/portable/GCC/RL78/isr_support.h

    /*
     * portSAVE_CONTEXT MACRO
     * Saves the context of the general purpose registers, CS and ES registers,
     * the usCriticalNesting Value and the Stack Pointer of the active Task
     * onto the task stack
     */
        .macro portSAVE_CONTEXT

        SEL     RB0

        /* Save the register bank 0. */
        PUSH    AX
        PUSH    BC
        PUSH    DE
        PUSH    HL
        /* Save CS register. */
        MOV     A, CS
        XCH     A, X
        /* Save ES register. */
        MOV     A, ES
        PUSH    AX
        /* Save the other register banks - only necessary in the GCC port. */
        ...略...
        /* Registers in bank 3 are for ISR use only so don't need saving. */
        SEL     RB0
        /* Save the usCriticalNesting value. */
        MOVW    AX, !_usCriticalNesting
        PUSH    AX
        /* Save the Stack pointer. */
        MOVW    AX, !_pxCurrentTCB
        MOVW    HL, AX
        MOVW    AX, SP
        MOVW    [HL], AX
        /* Switch stack pointers. */
        movw sp,#_stack /* Set stack pointer */

        .endm

    あと、以下は、dev guide debugの実行時、full demoの実行時、full demoのビルド時の画面コピーです。

    CC-RL + CS+ + ルネサスRL78シミュレータで実行




    CC-RL + e2 studio + ルネサスRL78シミュレータで実行




    GNURL78 + e2 studio + ルネサスRL78シミュレータで実行


Reply
  • こんにちは。NoMaYです。#3連投の1つ目です。

    今度はRenesas RL78 Simulatorでやってみました。残念ながらデバッグコンソール機能はありませんので、CS+ではPrintf Action Event機能を、e2 studioではDynamic Printf機能を、それぞれ使用しました。また、Simulator GUIにはLEDやButtonなどのGUI部品を並べたパネルを作成する機能がありますので、コード生成機能+FreeRTOSで割り込みを扱う簡単なプログラムを作成して、動作確認してみました。(今回は実機での確認をしてません。)

    以下、プロジェクトのファイル一式です。(CC-RL版はCS+ V8.01/e2 stuiod v7.40+CC-RX V1.02でビルド(e2 studio用.project/.cproject等を同梱))(GNURL78版はe2 studio v7.40+GNURL78 2019q2(4.9.2.201902)でビルド)(共にzipファイルをe2 studioに直接インポート可能) プロジェクト構造は極力RX版と同じにしてみました。

    sim_rl78_freertos_ccrl_c_csplus_20190612.zip    580KB
    sim_rl78_freertos_gnurl78_c_e2v740_20190612.zip    677KB

    以下、Printf Action Eventでの実行結果、Dynamic Printfでの実行結果、Simulator GUIでLEDとButtonを配置したパネル、の画面コピーです。







    今回のプロジェクトのベースは、別スレッド『FreeRTOSをFITやCG(や追々PDG2でも?)と一緒に使うサンプルプログラムをCSplusでビルド出来るプロジェクトにしてみた』のCC-RL版GNURL78版ですが、以下の小細工を追加しています。(なお、長時間運転の件は1年放置してしまっています。すみません、、、)

    (1) コード生成されたr_cg_macrodriver.hとFreeRTOSが使用するstdint.hとのint8_t/uint8_t等のtypedefの衝突の回避(CC-RL)
    (2) コード生成されたr_cg_vector_table.cにFreeRTOSのvPortTickISRとvPortYieldをスクリプトで自動ベクタ登録する(GNURL78)

    また、作業していて、以下の点には留意しておいた方が良さそうな気がしました。

    (3) FreeRTOSのstream_buffer.cでCC-RLの「偶数アライメントのオブジェクトを指すポインタが奇数番地を保持しています」が出る
    (4) FreeRTOSのGNURL78版では割り込み用スタックが使用されるが多重割り込みに対応していない(他方CC-RL版では使用されない)

    以下、その詳細です。

    (1) コード生成されたr_cg_macrodriver.hとFreeRTOSが使用するstdint.hとのint8_t/uint8_t等のtypedefの衝突の回避(CC-RL)

    幸い、FreeRTOSが使用するint8_t/uint8_t等のtypedefはr_cg_macrodriver.hに記述されているもので足りるようでしたので、以下のように小細工しました。(赤文字箇所)

    src/frtos_startup/freertos_start.h

    #include "r_cg_macrodriver.h"
    #include "r_cg_userdefine.h"
    #if defined(__CCRL__)
    #define _STDINT_H
    #endif
    #include "FreeRTOS.h"
    #include "task.h"
    #include "semphr.h"
    #include "queue.h"
    #include "croutine.h"
    #include "timers.h"
    #include "event_groups.h"

    (2) コード生成されたr_cg_vector_table.cにFreeRTOSのvPortTickISRとvPortYieldをスクリプトで自動ベクタ登録する(GNURL78)

    今回、r_cg_vector_table.jsというスクリプトを作成して、ビルド時に自動的に実行されるようにしました。このスクリプトでr_cg_vector_table.cを以下のように書き換えます。FreeRTOSのvPortTickISRとvPortYieldの他にも利用出来るよう、ちょっと大げさに書き換えることにしました。

    src/r_cg_vector_table.c

    自動書き換え前

    #include "r_cg_macrodriver.h"
    #include "r_cg_userdefine.h"

    ...略...

    #define VECT_SECT          __attribute__ ((section (".vects")))
    const void *Vectors[] VECT_SECT  = {
        // Address 0x4
        R_Dummy,
        ...略...
        // Address 0x7E
        R_Dummy,
    };

    自動書き換え後

    #include "r_cg_macrodriver.h"
    #include "r_cg_userdefine.h"
    #include "r_cg_vector_table.h"

    ...略...
    #define VECT_SECT          __attribute__ ((section (".vects")))
    const void *Vectors[] VECT_SECT  = {
        // Address 0x4
        R_Vector_0x4,
        ...略...
        // Address 0x7E
        R_Vector_0x7E,
    };

    そして、新規追加したr_cg_vector_table.hで以下のように任意のベクタを登録出来るようにしてみました。

    src/r_cg_vector_table.h

    /* Defines for user */

    /*
     * INT_IT (0x38 or 0x3C)
     */
    #if INTIT_vect == 0x38

    #define R_Vector_0x38 vPortTickISR

    #elif INTIT_vect == 0x3C

    #define R_Vector_0x3C vPortTickISR

    #else

    #error Neither vector 0x38 nor vector 0x3C is available for the tick interrupt.

    #endif

    /*
     * INT_BRK_I (0x7E)
     */
    #define R_Vector_0x7E vPortYield

    void vPortTickISR(void) __attribute__ ((interrupt));
    void vPortYield(void) __attribute__ ((interrupt));

    /* Defines for default */

    #ifndef R_Vector_0x4
    #define R_Vector_0x4  R_Dummy
    #endif
    ...略...
    #ifndef R_Vector_0x7E
    #define R_Vector_0x7E R_Dummy
    #endif

    (3) FreeRTOSのstream_buffer.cでCC-RLの「偶数アライメントのオブジェクトを指すポインタが奇数番地を保持しています」が出る

    CC-RLでコンパイルすると以下のワーニングが出ます。(GNURL78では出ませんがチェックしていないからです。) もしstream_buffer.cの機能を使用するのであれば、問題無いかどうか確認してから使用する必要があります。(今回、ちょっと気力不足で、私はFreeRTOSのソースを調べていないです。)

    src\FreeRTOS\Source\stream_buffer.c(262):W0523082:偶数アライメントのオブジェクトを指すポインタが奇数番地を保持しています。
    src\FreeRTOS\Source\stream_buffer.c(275):W0523082:偶数アライメントのオブジェクトを指すポインタが奇数番地を保持しています。

    (4) FreeRTOSのGNURL78版では割り込み用スタックが使用されるが多重割り込みに対応していない(他方CC-RL版では使用されない)

    もともとFreeRTOS 10.2.1のソースにCC-RL版はありませんので正確にはCC-RL版のベースにしたIAR版では使用されていない、ということなのですが、それに対してGNURL78版では以下のように割り込み用スタックへの切り替えが行われています。FreeRTOSカーネル自体は多重割り込み対応だろうとは思っていますが、以下の部分が多重割り込みでは誤動作する(多重割り込みでスタックポインタが割り込み用スタックの初期値に戻ってしまう)ので、もしGNURL78版でFreeRTOS APIを多重割り込み内から呼び出すようなことをしたければ改造が必要です。

    src/FreeRTOS/Source/portable/GCC/RL78/isr_support.h

    /*
     * portSAVE_CONTEXT MACRO
     * Saves the context of the general purpose registers, CS and ES registers,
     * the usCriticalNesting Value and the Stack Pointer of the active Task
     * onto the task stack
     */
        .macro portSAVE_CONTEXT

        SEL     RB0

        /* Save the register bank 0. */
        PUSH    AX
        PUSH    BC
        PUSH    DE
        PUSH    HL
        /* Save CS register. */
        MOV     A, CS
        XCH     A, X
        /* Save ES register. */
        MOV     A, ES
        PUSH    AX
        /* Save the other register banks - only necessary in the GCC port. */
        ...略...
        /* Registers in bank 3 are for ISR use only so don't need saving. */
        SEL     RB0
        /* Save the usCriticalNesting value. */
        MOVW    AX, !_usCriticalNesting
        PUSH    AX
        /* Save the Stack pointer. */
        MOVW    AX, !_pxCurrentTCB
        MOVW    HL, AX
        MOVW    AX, SP
        MOVW    [HL], AX
        /* Switch stack pointers. */
        movw sp,#_stack /* Set stack pointer */

        .endm

    あと、以下は、dev guide debugの実行時、full demoの実行時、full demoのビルド時の画面コピーです。

    CC-RL + CS+ + ルネサスRL78シミュレータで実行




    CC-RL + e2 studio + ルネサスRL78シミュレータで実行




    GNURL78 + e2 studio + ルネサスRL78シミュレータで実行


Children
No Data