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です。

    今度もRenesas RL78 Simulatorですが、2.5μsec毎に100回連続A/D変換させてDMAでデータを取り込んでみました。ベースにしたプロジェクトは以前に『RL78/G13で2.5μsec毎に100回連続A/D変換させてDMAでデータを取り込むコードをコード生成させてシミュレータと実デバイスで試してみた』に投稿したものです。以下、プロジェクトのファイル一式です。(今回もプロジェクトは1つだけです。) (また、今回も実機では確認してません。)

    sim_rl78_freertos_ccrl_c_csplus_20190619.zip    673KB
    sim_rl78_freertos_gnurl78_c_e2v740_20190619.zip    625KB

    以下、CS+での画面コピーです。(e2 studioでも同様です。)




    今回、以下の部分で割り込みの発生待ちをするようにしてみました。(赤文字箇所)

    src/user_main.c

    void intp_timer_adc_dmac_demo_task(void *pvParameters)
    {
        uint8_t count;
        
        (void) pvParameters;
        NOP();  /* for breakpoint, start singnal input on Simulator GUI */

        taskENTER_CRITICAL();
        LED_INIT();
        taskEXIT_CRITICAL();

        R_INTC3_Start();

        R_ADC_Set_OperationOn();
        for (count = 0U ; count < 32U ; count++)    /* Waiting for comparator stabilizing */
        {
            NOP();
        }

        for (;;)
        {
            /* --- Waiting for a click of button on Simulator GUI --- */
            xSemaphoreTake( xSemaphoreINTP3, portMAX_DELAY );

            taskENTER_CRITICAL();
            LED_BIT = !LED_BIT;
            taskEXIT_CRITICAL();

            R_DMAC0_UserInit();

            /* --- Start TAU and A/D Convert and DMA --- */
            R_DMAC0_Start();                        /* Enable DMA : Start waiting DMA trigger */
            R_ADC_Start();                          /* Enable A/D : Start waiting A/D trigger */
            R_TAU0_Channel1_Lower8bits_Start();     /* Start! */

            /* --- A/D converting now --- */
            xSemaphoreTake( xSemaphoreINTDMA0, portMAX_DELAY );

            /* --- Stop TAU and A/D Convert and DMA --- */
            R_TAU0_Channel1_Lower8bits_Stop();
            R_ADC_Stop();
            R_DMAC0_Stop();

            taskENTER_CRITICAL();
            LED_BIT = !LED_BIT;
            taskEXIT_CRITICAL();

            NOP();  /* for trace start, check timing chart on Simulator GUI
                    after trace full break */
        }
    }

    割り込みルーチンは以下の通りです。(CC-RLの場合のものですがGNURL78でも同様です。)

    src/r_cg_intc_user.c

    #pragma interrupt r_intc3_interrupt(vect=INTP3)
    /* Start user code for pragma. Do not edit comment generated here */
    R_PRAGMA_FREERTOS_INTERRUPT(r_intc3_interrupt)
    #define r_intc3_interrupt _r_intc3_interrupt
    /* End user code. Do not edit comment generated here */
    static void __near r_intc3_interrupt(void)
    {
        /* Start user code. Do not edit comment generated here */

        short sHigherPriorityTaskWoken = pdFALSE;

        xSemaphoreGiveFromISR( xSemaphoreINTP3, &sHigherPriorityTaskWoken );
        portYIELD_FROM_ISR( sHigherPriorityTaskWoken );

        /* End user code. Do not edit comment generated here */
    }

    src/r_cg_dma_user.c

    #pragma interrupt r_dmac0_interrupt(vect=INTDMA0)
    /* Start user code for pragma. Do not edit comment generated here */
    R_PRAGMA_FREERTOS_INTERRUPT(r_dmac0_interrupt)
    #define r_dmac0_interrupt _r_dmac0_interrupt
    /* End user code. Do not edit comment generated here */
    static void __near r_dmac0_interrupt(void)
    {
        /* Start user code. Do not edit comment generated here */

        short sHigherPriorityTaskWoken = pdFALSE;

        xSemaphoreGiveFromISR( xSemaphoreINTDMA0, &sHigherPriorityTaskWoken );
        portYIELD_FROM_ISR( sHigherPriorityTaskWoken );

        /* End user code. Do not edit comment generated here */
    }

    また、先日の投稿と同様に、各タスクでポート出力をトグルさせています。

    src/user_main.c

    void main_task(void *pvParameters)
    {
        (void) pvParameters;

        while (1)
        {
            taskENTER_CRITICAL();
            P1_bit.no6 = !P1_bit.no6;
            taskEXIT_CRITICAL();
        }
    }

    void second_task(void *pvParameters)
    {
        (void) pvParameters;

        while (1)
        {
            taskENTER_CRITICAL();
            P1_bit.no5 = !P1_bit.no5;
            taskEXIT_CRITICAL();
        }
    }

    void third_task(void *pvParameters)
    {
        (void) pvParameters;

        while (1)
        {
            taskENTER_CRITICAL();
            P1_bit.no4 = !P1_bit.no4;
            taskEXIT_CRITICAL();
        }
    }

     

Reply
  • こんにちは。NoMaYです。

    今度もRenesas RL78 Simulatorですが、2.5μsec毎に100回連続A/D変換させてDMAでデータを取り込んでみました。ベースにしたプロジェクトは以前に『RL78/G13で2.5μsec毎に100回連続A/D変換させてDMAでデータを取り込むコードをコード生成させてシミュレータと実デバイスで試してみた』に投稿したものです。以下、プロジェクトのファイル一式です。(今回もプロジェクトは1つだけです。) (また、今回も実機では確認してません。)

    sim_rl78_freertos_ccrl_c_csplus_20190619.zip    673KB
    sim_rl78_freertos_gnurl78_c_e2v740_20190619.zip    625KB

    以下、CS+での画面コピーです。(e2 studioでも同様です。)




    今回、以下の部分で割り込みの発生待ちをするようにしてみました。(赤文字箇所)

    src/user_main.c

    void intp_timer_adc_dmac_demo_task(void *pvParameters)
    {
        uint8_t count;
        
        (void) pvParameters;
        NOP();  /* for breakpoint, start singnal input on Simulator GUI */

        taskENTER_CRITICAL();
        LED_INIT();
        taskEXIT_CRITICAL();

        R_INTC3_Start();

        R_ADC_Set_OperationOn();
        for (count = 0U ; count < 32U ; count++)    /* Waiting for comparator stabilizing */
        {
            NOP();
        }

        for (;;)
        {
            /* --- Waiting for a click of button on Simulator GUI --- */
            xSemaphoreTake( xSemaphoreINTP3, portMAX_DELAY );

            taskENTER_CRITICAL();
            LED_BIT = !LED_BIT;
            taskEXIT_CRITICAL();

            R_DMAC0_UserInit();

            /* --- Start TAU and A/D Convert and DMA --- */
            R_DMAC0_Start();                        /* Enable DMA : Start waiting DMA trigger */
            R_ADC_Start();                          /* Enable A/D : Start waiting A/D trigger */
            R_TAU0_Channel1_Lower8bits_Start();     /* Start! */

            /* --- A/D converting now --- */
            xSemaphoreTake( xSemaphoreINTDMA0, portMAX_DELAY );

            /* --- Stop TAU and A/D Convert and DMA --- */
            R_TAU0_Channel1_Lower8bits_Stop();
            R_ADC_Stop();
            R_DMAC0_Stop();

            taskENTER_CRITICAL();
            LED_BIT = !LED_BIT;
            taskEXIT_CRITICAL();

            NOP();  /* for trace start, check timing chart on Simulator GUI
                    after trace full break */
        }
    }

    割り込みルーチンは以下の通りです。(CC-RLの場合のものですがGNURL78でも同様です。)

    src/r_cg_intc_user.c

    #pragma interrupt r_intc3_interrupt(vect=INTP3)
    /* Start user code for pragma. Do not edit comment generated here */
    R_PRAGMA_FREERTOS_INTERRUPT(r_intc3_interrupt)
    #define r_intc3_interrupt _r_intc3_interrupt
    /* End user code. Do not edit comment generated here */
    static void __near r_intc3_interrupt(void)
    {
        /* Start user code. Do not edit comment generated here */

        short sHigherPriorityTaskWoken = pdFALSE;

        xSemaphoreGiveFromISR( xSemaphoreINTP3, &sHigherPriorityTaskWoken );
        portYIELD_FROM_ISR( sHigherPriorityTaskWoken );

        /* End user code. Do not edit comment generated here */
    }

    src/r_cg_dma_user.c

    #pragma interrupt r_dmac0_interrupt(vect=INTDMA0)
    /* Start user code for pragma. Do not edit comment generated here */
    R_PRAGMA_FREERTOS_INTERRUPT(r_dmac0_interrupt)
    #define r_dmac0_interrupt _r_dmac0_interrupt
    /* End user code. Do not edit comment generated here */
    static void __near r_dmac0_interrupt(void)
    {
        /* Start user code. Do not edit comment generated here */

        short sHigherPriorityTaskWoken = pdFALSE;

        xSemaphoreGiveFromISR( xSemaphoreINTDMA0, &sHigherPriorityTaskWoken );
        portYIELD_FROM_ISR( sHigherPriorityTaskWoken );

        /* End user code. Do not edit comment generated here */
    }

    また、先日の投稿と同様に、各タスクでポート出力をトグルさせています。

    src/user_main.c

    void main_task(void *pvParameters)
    {
        (void) pvParameters;

        while (1)
        {
            taskENTER_CRITICAL();
            P1_bit.no6 = !P1_bit.no6;
            taskEXIT_CRITICAL();
        }
    }

    void second_task(void *pvParameters)
    {
        (void) pvParameters;

        while (1)
        {
            taskENTER_CRITICAL();
            P1_bit.no5 = !P1_bit.no5;
            taskEXIT_CRITICAL();
        }
    }

    void third_task(void *pvParameters)
    {
        (void) pvParameters;

        while (1)
        {
            taskENTER_CRITICAL();
            P1_bit.no4 = !P1_bit.no4;
            taskEXIT_CRITICAL();
        }
    }

     

Children
No Data