e2 studio v7.5.0のFreeRTOS ProjectでVisual Expression+Renesas RX Simulator/TB-RX65Nで試せるSample Programを作ってみた

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

今は(今後も?)e2 studioでのみ作れるFreeRTOSプロジェクトですが、以下のプログラムを作ってみました。

TB-RX65N用

(1) TBボードのLED0を500ms毎にOn/Offする(FreeRTOS APIのvTaskDelay()を使用)
(2) TBボードのSW1押下毎にLED1をOn/Offする(タスクでセマフォ待ちして割り込みでセマフォ待ち解除)
(3) TBボードのSCI1で3文字受信毎に3文字エコーバックする(タスクでセマフォ待ちして割り込みで3文字毎にセマフォ待ち解除)

Renesas RX Simulator用

(1') Visual ExpressionのLED部品を50ms(但しシミュレーション上の時間)毎にOn/Offする(上の(1)の括弧内と同様)
(2') Visual ExpressionのBUTTON部品押下毎にLED部品をOn/Offする(上の(2)の括弧内と同様)
(3') Renesas Debug Virtual Console⇔SCI1で3文字受信毎に3文字エコーバックする(上の(3)の括弧内と同様)

プロジェクトのファイル一式 (CC-RX V2.03でビルド、zipファイルをe2 studioに直接インポート可能)
japan.renesasrulz.com/cafe_rene/m/sample_program/434
sim_rx65n_freertos_proj_fit_scfg_ccrx_c_e2v750_20190924.zip    1.23MB
sim_rx65n_freertos_proj_fit_scfg_ccrx_c_e2v760_20191019.zip    1.23MB (主にGNURX版との合わせ込みです)

含まれるプロジェクト
sim_rx65n_freertos_proj_fit_scfg ← こちら側にソースがあります(TB-RX65Nでも動作可)(*1,*2)
tb_rx65n_freertos_proj_fit_scfg ← こちら側にソースは無いです(TB側はSIM側のソースフォルダをリンク機能で参照します)(*1,*2)
x_DO_NOT_BUILD_rx65n_freertos_proj_fit_scfg_0 ← ソース編集前のRXスマートコンフィグレータ設定直後のソース(*3)

*1:以前に別スレッド「RenesasさんからRXマイコンの低価格Target Boardが出たのでサンプルプログラムをCSplus projectへ変換してみようと思います」に投稿したプロジェクトと同じIDコードを設定しています。

*2:実機用の.launchファイルは当方特有の事情でオンボードエミュレータが使えない為に未確認です。

*3:RXスマートコンフィグレータの設定を行った直後にRXスマートコンフィグレータに生成させたソースがx_DO_NOT_BUILD_rx65n_freertos_proj_fit_scfg_0プロジェクトのsrcフォルダのソースです。ファイル比較ツールで比較することで、RXスマートコンフィグレータに生成させた後、どのように編集したか分かります。

出来るだけ同じプログラムにしたかった/する為に、Renesas RX Simulator用に以下の#if~#else~#endifがあります。(私のパソコンの遅さゆえにそうしたものもあります。)

(A) Visual ExpressionのBUTTON部品押下からのPORTB.PIDR.BIT.B1書き換えをポーリングしてIRQ4割り込みをエミュレート
(B) Renesas Debug Virtual Consoleからの受信到着待ちをポーリングしてSCI1のRXI1割り込みをエミュレート
(C) Renesas Debug Virtual Consoleへの送信可能待ちをポーリングしてSCI1のTXI1/TEI1(*3)割り込みをエミュレート
(D) FreeRTOSのRX600v2ポートレイヤは別スレッドで試したRenesas RX Simulator用の無理矢理な代替実装を使用(実機動作可)
(E) その別スレッドで試したr_bspモジュールのクロック切り替え時の無限ループ対処をフラッシュキャッシュ有効化時にも適用
(F) TB-RX65N用では500msの点滅間隔をRenesas RX Simulator用では50ms(但しシミュレーション上の時間)の点滅間隔に変更
(G) TB-RX65N用では10msのチャタリング除去待ち時間をRenesas RX Simulator用では待ち時間は無しに変更

*3:もう少し正確に書くとTEI1の動作ではなくICUのGROUPBL0割り込みとGROUPBL0のビット6の動作に関してです。

コーディング上の小技として以下のこともやってみました。

(H) CGコンポーネント初期化用のr_cg_hardware_setup.cでFITモジュール端子設定関数を呼ぶStart user code~End user code内の記述
(I) r_bspモジュールのソースを直接変更せずにRenesas RX Simulator用の無限ループ対処を組み込む#defineマクロ

FreeRTOS関連では以下のような設定変更や記述追加も行いました。

(a) r_bsp_config.h
(a-1) Uスタックサイズを0へ(FreeRTOS管理下のメモリがタスクのスタックに使われるので)(Iスタックはそのまま使われます)
(a-2) Heapサイズを0へ(FreeRTOS管理下のメモリをFreeRTOSのスレッドセーフなAPIで操作する方が安全と思われますので)
(b) FreeRTOSConfig.h
(b-1) #define __TYPEDEF__ 1 を削除
(b-2) #define configINCLUDE_PLATFORM_H_INSTEAD_OF_IODEFINE_H 1 を追加
(b-3) #define configENABLE_BACKWARD_COMPATIBILITY 0 を追加
(c) freertos_start.c
(c-1) 別スレッド同様にRenesas RX Simulator用のRX600v2ポートレイヤの無理矢理な代替実装で使うCMT1の重複エラーを追加
(c-2) 別スレッド同様にAmazon AWSのFreeRTOS Kernel Developer Guideのサンプルコードを試せるようにvPrintString()を追加
(c-3) vAssertCalled(), vApplicationMallocFailedHook(), vApplicationStackOverflowHook()でvPrintString()でメッセージを出力
(c-4) vApplicationTickHook()でIRQ4やSIC1の割り込み動作エミュレート用の関数を呼び出す(ここが一番手っ取り早そうだった)
(c-5) FreeRTOSプロジェクトでmain_task()がFreeRTOS Objectコンポーネント管理外なので対処(今回はmain_task()は空です)
(c-1) Heapサイズを0にするとsbrk()が無いというリンクエラーになってしまうのでエラー処理のみのsbrk()を追加

後日手を入れたいと思っていることに以下のことがあります。

(イ) R_SCI_RXモジュールのAPI+FreeRTOS APIで受信エラーをタスク側で拾うにはどうすると良いか?(RL78ではこうしたけれど)
(ロ) 最終的に使わなかったR_CMT_RXモジュールとRX600v2ポートレイヤの無理矢理な代替実装の両方でCMT1の使用が重複してしまう問題への対処(R_CMT_RXモジュールに手を入れるか?)

この後、2投目~5投目は以下の通りです。

2投目

・IRQ4割り込みエミュレーションのソース (大げさなものでは無いです)
・SCI1のRXI1/TXI1/TEI1(前述の*3を参照)割り込みエミュレーションのソース (大げさなものでは無いです)
・CGコンポーネント初期化用のr_cg_hardware_setup.cでFITモジュール端子設定関数を呼ぶStart user code~End user code内の記述
・r_bspモジュールのソースを直接変更せずにRenesas RX Simulator用の無限ループ対処を組み込む#defineマクロ

3投目

・FreeRTOSプロジェクトでmain_task()がFreeRTOS Objectコンポーネント管理外なので対処(今回はmain_task()は空です)
・tb_rx65n_main.c, main_task.c, task_LED0.c, task_LED1.c, task_CONIO.cのソース

4投目 (ひたすら画面コピーです)

・Visual Expressionの部品の設定
・Visual Expressionの設定
・Renesas Debug Virtual Consoleの設定
・コンソールのCOMポートの設定

5投目 (ひたすら画面コピーです)

・RXスマートコンフィグレータの設定

以下、画面コピーと写真です。

Renesas RX Simulatorで実行


TB-RX65Nで実行



RXスマートコンフィグレータに生成させた後に編集/追加したソース(右側のペイン)


[履歴]

sim_rx65n_freertos_proj_fit_scfg_ccrx_c_e2v750_20190924.zip
・初版

sim_rx65n_freertos_proj_fit_scfg_ccrx_c_e2v760_20191019.zip
・MOTファイルは変わりません
・VOLATILEマクロ追加(GNURX版との合わせ込み)
 変更ファイル: src/smc_gen/r_config/r_bsp_config.h, src/sim_rx65n_int_emulation.c
・machine.hファイル追加(CC-RX版では未使用)(GNURX版との合わせ込み)
 追加ファイル: src/r_bsp_modified/GNURX_support/machine.h
 変更ファイル: src/smc_gen/r_config/r_bsp_config.h
・GNURX版でのワーニング対処の反映(GNURX版との合わせ込み)
 変更ファイル: src/smc_gen/r_pincfg/Pin.c
・スタック情報ファイルを生成するプロジェクト設定を追加
 変更ファイル: .cproject
・実機用の.lauchファイルを追加(当方特有の事情でオンボードエミュレータが使えない為に未確認です)
 追加ファイル: "sim_rx65n_freertos_proj_fit HardwareDebug.launch", "tb_rx65n_freertos_proj_fit HardwareDebug.launch"

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

    今回のFreeRTOSプロジェクトのタスクは以下の画面コピーの通りです。



    但し、ちょっとmain_task()は例外的であり、もともと、FreeRTOSプロジェクト生成時にメインのソース内に出力されたmain_task()が存在しており、かつ、その時点で、main_task()の生成処理もfreertos_start.c内のProcessing_Before_Start_Kernel()内に記述されていて、RXスマートコンフィグレータのFreeRTOS Objectと別扱いになっています。(FreeRTOSオブジェクトの場合は、各タスクのソースはfrtos_skeletonフォルダ内のタスク名.cに出力されており、また、各タスクの生成処理はfrtos_startupフォルダ内のfreertos_object_init.c内に出力されています。) とはいえ、main_task()も他タスクと同様にRXスマートコンフィグレータにFreeRTOS Objectとして表示させたいので、今回は、以下のように対処することにしました。

    src/frtos_skeleton/main_task.c

    #include "task_function.h"
    /* Start user code for import. Do not edit comment generated here */
    #if 0
    /* End user code. Do not edit comment generated here */

    void main_task(void * pvParameters)
    {
    /* Start user code for function. Do not edit comment generated here */
    /* End user code. Do not edit comment generated here */
    }
    /* Start user code for other. Do not edit comment generated here */
    #endif /* #if 0 */
    /* End user code. Do not edit comment generated here */

    src/frtos_startup/freertos_start.c

    void Processing_Before_Start_Kernel(void)
    {
    #if 0
        BaseType_t ret;
    #endif /* #if 0 */



    #if 0
        /************** task creation ****************************/
        /* Main task. */
        ret = xTaskCreate(main_task, "MAIN_TASK", 512, NULL, 3, NULL);
        if (pdPASS != ret)
        {
            while(1)
            {
                /* Failed! Task can not be created. */
            }
        }
    #endif /* #if 0 */

    } /* End of function Processing_Before_Start_Kernel() */

    但し、今回は、main_task()は以下の通りに空となっています。(空とは言え、CPU時間は消費しています。)

    src/tb_rx65n_main.c

    tb_rx65n_main_c_20190919.txt
    #include "task_function.h"
    #include "freertos_start.h"
    #include "platform.h"
    
    void main_task(void *pvParameters)
    {
    
        INTERNAL_NOT_USED(pvParameters);
    
        /* Create all other application tasks here */
    
        while(1);
    
        /* vTaskDelete(NULL); */
    
    }
    


    なお、他のタスクのソースは以下の通りです。(ヘッダ等は省略しています。上のソースも同じです。)

    src/frtos_skeleton/task_LED0.c
    task_LED0_c_20190918.txt
    #include "task_function.h"
    /* Start user code for import. Do not edit comment generated here */
    #include "freertos_start.h"
    #include "platform.h"
    #include "tbrx65ndef.h"
    /* End user code. Do not edit comment generated here */
    
    void task_LED0(void * pvParameters)
    {
    /* Start user code for function. Do not edit comment generated here */
    
        INTERNAL_NOT_USED( pvParameters );
    
        LED0 = LED_ON;
        for (;;)
        {
    #if defined(RENESAS_SIMULATOR_DEBUGGING)
            if (IsRenesasSimDebugMode())
            {
                /* Renesas RX Simulator */
                vTaskDelay( pdMS_TO_TICKS( 50/*ms(as of the simulation time)*/ ) );
            }
            else
    #endif
            {
                /* Hardware */
                vTaskDelay( pdMS_TO_TICKS( 500/*ms*/ ) );
            }
            LED0 = ~LED0;
        }
    
    /* End user code. Do not edit comment generated here */
    }
    /* Start user code for other. Do not edit comment generated here */
    /* End user code. Do not edit comment generated here */
    


    src/frtos_skeleton/task_LED1.c
    task_LED1_c_20190918.txt
    #include "task_function.h"
    /* Start user code for import. Do not edit comment generated here */
    #include "freertos_start.h"
    #include "platform.h"
    #include "r_irq_rx_if.h"
    #include "r_irq_rx_config.h"
    #include "tbrx65ndef.h"
    
    static void my_irq4_callback( void *pdata );
    
    /* End user code. Do not edit comment generated here */
    
    void task_LED1(void * pvParameters)
    {
    /* Start user code for function. Do not edit comment generated here */
    
        INTERNAL_NOT_USED( pvParameters );
    
        irq_err_t       my_error_code;
        irq_handle_t    my_irq4_handle;
    
        my_error_code = R_IRQ_Open( IRQ_NUM_4, IRQ_TRIG_FALLING, IRQ_PRI_2, &my_irq4_handle, my_irq4_callback );
        if (IRQ_SUCCESS != my_error_code)
        {
            for(;;); /* TODO: Handle an error */
        }
    
        LED1 = LED_OFF;
        for (;;)
        {
            xSemaphoreTake( semaphore_handle_SW1_PUSH, portMAX_DELAY );
    
            /* Remove mechanical switch chattering */
    #if defined(RENESAS_SIMULATOR_DEBUGGING)
            if (IsRenesasSimDebugMode())
            {
                /* Renesas RX Simulator */
                /* Nothing to do */
            }
            else
    #endif
            {
                /* Hardware */
                vTaskDelay( pdMS_TO_TICKS( 10/*ms*/ ) );
            }
            xSemaphoreTake( semaphore_handle_SW1_PUSH, 0 );
    
            if (SW1_PUSH == SW1)
            {
                LED1 = ~LED1;
            }
        }
    
    /* End user code. Do not edit comment generated here */
    }
    /* Start user code for other. Do not edit comment generated here */
    
    void my_irq4_callback(void *pdata)
    {
        INTERNAL_NOT_USED( pdata );
    
        BaseType_t sHigherPriorityTaskWoken = pdFALSE;
    
        xSemaphoreGiveFromISR( semaphore_handle_SW1_PUSH, &sHigherPriorityTaskWoken );
        portYIELD_FROM_ISR( sHigherPriorityTaskWoken );
    }
    
    /* End user code. Do not edit comment generated here */
    


    src/frtos_skeleton/task_CONIO.c
    task_CONIO_c_20190918.txt
    #include "task_function.h"
    /* Start user code for import. Do not edit comment generated here */
    #include "freertos_start.h"
    #include "platform.h"
    #include "r_sci_rx_if.h"
    #include "r_sci_rx_config.h"
    #include "r_byteq_if.h"
    
    static uint16_t my_sci_rx_length = 0;
    static volatile uint16_t my_sci_rx_count = 0;
    
    static void my_sci_callback(void *pArgs);
    
    /* End user code. Do not edit comment generated here */
    
    void task_CONIO(void * pvParameters)
    {
    /* Start user code for function. Do not edit comment generated here */
    
        INTERNAL_NOT_USED( pvParameters );
    
        sci_err_t   my_sci_err;
        sci_hdl_t   my_sci_handle;
        sci_cfg_t   my_sci_config;
        uint8_t     my_char[3];
    
        my_sci_config.async.baud_rate    = 115200;
        my_sci_config.async.clk_src      = SCI_CLK_INT;
        my_sci_config.async.data_size    = SCI_DATA_8BIT;
        my_sci_config.async.parity_en    = SCI_PARITY_OFF;
        my_sci_config.async.parity_type  = SCI_EVEN_PARITY;
        my_sci_config.async.stop_bits    = SCI_STOPBITS_1;
        my_sci_config.async.int_priority = 3;    // 1=lowest, 15=highest
    
        my_sci_err = R_SCI_Open(SCI_CH1, SCI_MODE_ASYNC, &my_sci_config, my_sci_callback, &my_sci_handle);
        if (SCI_SUCCESS != my_sci_err)
        {
            for(;;); /* TODO: Handle an error */
        }
    
        for (;;)
        {
            taskENTER_CRITICAL(); // or taskDISABLE_INTERRUPTS()
            {
                // FIXME: This is a super ultra tentative code :(
                my_sci_rx_length = 3;
                my_sci_rx_count = 0;
            }
            taskEXIT_CRITICAL(); // or taskENABLE_INTERRUPTS()
            xSemaphoreTake( semaphore_handle_CON_RX_READY, portMAX_DELAY );
    
            my_sci_err = R_SCI_Receive(my_sci_handle, my_char, my_sci_rx_length);
            if (SCI_SUCCESS != my_sci_err)
            {
                for(;;); /* TODO: Handle an error */
            }
    
            my_sci_err = R_SCI_Send(my_sci_handle, my_char, my_sci_rx_length);
            if (SCI_SUCCESS != my_sci_err)
            {
                for(;;); /* TODO: Handle an error */
            }
        }
    
    /* End user code. Do not edit comment generated here */
    }
    /* Start user code for other. Do not edit comment generated here */
    
    void my_sci_callback(void *pArgs)
    {
    sci_cb_args_t   *args;
    
        args = (sci_cb_args_t *)pArgs;
    
        if (args->event == SCI_EVT_RX_CHAR)
        {
            /* From RXI interrupt; received character data is in args->byte */
            my_sci_rx_count++;
            if (my_sci_rx_count == my_sci_rx_length)
            {
                BaseType_t sHigherPriorityTaskWoken = pdFALSE;
    
                xSemaphoreGiveFromISR( semaphore_handle_CON_RX_READY, &sHigherPriorityTaskWoken );
                portYIELD_FROM_ISR( sHigherPriorityTaskWoken );
            }
            else if (my_sci_rx_count > my_sci_rx_length)
            {
                /* Prevent from doing xSemaphoreGiveFromISR() more than once */
                /* Nothing to do */
            }
        }
    #if SCI_CFG_CH1_DATA_MATCH_INCLUDED
        else if (args->event == SCI_EVT_RX_CHAR_MATCH)
        {
            /* From RXI interrupt; received match character data is in args->byte */
            nop();
        }
    #endif
    #if SCI_CFG_TEI_INCLUDED
        else if (args->event == SCI_EVT_TEI)
        {
            /* From TEI interrupt; transmitter is idle
               Possibly disable external transceiver here */
            nop();
        }
    #endif
        else if (args->event == SCI_EVT_RXBUF_OVFL)
        {
            /* From RXI interrupt; rx queue is full; 'lost' data is in args->byte
               You will need to increase buffer size or reduce baud rate */
            nop();
        }
        else if (args->event == SCI_EVT_OVFL_ERR)
        {
            /* From receiver overflow error interrupt; error data is in args->byte
               Error condition is cleared in calling interrupt routine */
            nop();
        }
        else if (args->event == SCI_EVT_FRAMING_ERR)
        {
            /* From receiver framing error interrupt; error data is in args->byte
               Error condition is cleared in calling interrupt routine */
            nop();
        }
        else if (args->event == SCI_EVT_PARITY_ERR)
        {
            /* From receiver parity error interrupt; error data is in args->byte
               Error condition is cleared in calling interrupt routine */
            nop();
        }
    }
    
    /* End user code. Do not edit comment generated here */
    

     

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

    今回のFreeRTOSプロジェクトのタスクは以下の画面コピーの通りです。



    但し、ちょっとmain_task()は例外的であり、もともと、FreeRTOSプロジェクト生成時にメインのソース内に出力されたmain_task()が存在しており、かつ、その時点で、main_task()の生成処理もfreertos_start.c内のProcessing_Before_Start_Kernel()内に記述されていて、RXスマートコンフィグレータのFreeRTOS Objectと別扱いになっています。(FreeRTOSオブジェクトの場合は、各タスクのソースはfrtos_skeletonフォルダ内のタスク名.cに出力されており、また、各タスクの生成処理はfrtos_startupフォルダ内のfreertos_object_init.c内に出力されています。) とはいえ、main_task()も他タスクと同様にRXスマートコンフィグレータにFreeRTOS Objectとして表示させたいので、今回は、以下のように対処することにしました。

    src/frtos_skeleton/main_task.c

    #include "task_function.h"
    /* Start user code for import. Do not edit comment generated here */
    #if 0
    /* End user code. Do not edit comment generated here */

    void main_task(void * pvParameters)
    {
    /* Start user code for function. Do not edit comment generated here */
    /* End user code. Do not edit comment generated here */
    }
    /* Start user code for other. Do not edit comment generated here */
    #endif /* #if 0 */
    /* End user code. Do not edit comment generated here */

    src/frtos_startup/freertos_start.c

    void Processing_Before_Start_Kernel(void)
    {
    #if 0
        BaseType_t ret;
    #endif /* #if 0 */



    #if 0
        /************** task creation ****************************/
        /* Main task. */
        ret = xTaskCreate(main_task, "MAIN_TASK", 512, NULL, 3, NULL);
        if (pdPASS != ret)
        {
            while(1)
            {
                /* Failed! Task can not be created. */
            }
        }
    #endif /* #if 0 */

    } /* End of function Processing_Before_Start_Kernel() */

    但し、今回は、main_task()は以下の通りに空となっています。(空とは言え、CPU時間は消費しています。)

    src/tb_rx65n_main.c

    tb_rx65n_main_c_20190919.txt
    #include "task_function.h"
    #include "freertos_start.h"
    #include "platform.h"
    
    void main_task(void *pvParameters)
    {
    
        INTERNAL_NOT_USED(pvParameters);
    
        /* Create all other application tasks here */
    
        while(1);
    
        /* vTaskDelete(NULL); */
    
    }
    


    なお、他のタスクのソースは以下の通りです。(ヘッダ等は省略しています。上のソースも同じです。)

    src/frtos_skeleton/task_LED0.c
    task_LED0_c_20190918.txt
    #include "task_function.h"
    /* Start user code for import. Do not edit comment generated here */
    #include "freertos_start.h"
    #include "platform.h"
    #include "tbrx65ndef.h"
    /* End user code. Do not edit comment generated here */
    
    void task_LED0(void * pvParameters)
    {
    /* Start user code for function. Do not edit comment generated here */
    
        INTERNAL_NOT_USED( pvParameters );
    
        LED0 = LED_ON;
        for (;;)
        {
    #if defined(RENESAS_SIMULATOR_DEBUGGING)
            if (IsRenesasSimDebugMode())
            {
                /* Renesas RX Simulator */
                vTaskDelay( pdMS_TO_TICKS( 50/*ms(as of the simulation time)*/ ) );
            }
            else
    #endif
            {
                /* Hardware */
                vTaskDelay( pdMS_TO_TICKS( 500/*ms*/ ) );
            }
            LED0 = ~LED0;
        }
    
    /* End user code. Do not edit comment generated here */
    }
    /* Start user code for other. Do not edit comment generated here */
    /* End user code. Do not edit comment generated here */
    


    src/frtos_skeleton/task_LED1.c
    task_LED1_c_20190918.txt
    #include "task_function.h"
    /* Start user code for import. Do not edit comment generated here */
    #include "freertos_start.h"
    #include "platform.h"
    #include "r_irq_rx_if.h"
    #include "r_irq_rx_config.h"
    #include "tbrx65ndef.h"
    
    static void my_irq4_callback( void *pdata );
    
    /* End user code. Do not edit comment generated here */
    
    void task_LED1(void * pvParameters)
    {
    /* Start user code for function. Do not edit comment generated here */
    
        INTERNAL_NOT_USED( pvParameters );
    
        irq_err_t       my_error_code;
        irq_handle_t    my_irq4_handle;
    
        my_error_code = R_IRQ_Open( IRQ_NUM_4, IRQ_TRIG_FALLING, IRQ_PRI_2, &my_irq4_handle, my_irq4_callback );
        if (IRQ_SUCCESS != my_error_code)
        {
            for(;;); /* TODO: Handle an error */
        }
    
        LED1 = LED_OFF;
        for (;;)
        {
            xSemaphoreTake( semaphore_handle_SW1_PUSH, portMAX_DELAY );
    
            /* Remove mechanical switch chattering */
    #if defined(RENESAS_SIMULATOR_DEBUGGING)
            if (IsRenesasSimDebugMode())
            {
                /* Renesas RX Simulator */
                /* Nothing to do */
            }
            else
    #endif
            {
                /* Hardware */
                vTaskDelay( pdMS_TO_TICKS( 10/*ms*/ ) );
            }
            xSemaphoreTake( semaphore_handle_SW1_PUSH, 0 );
    
            if (SW1_PUSH == SW1)
            {
                LED1 = ~LED1;
            }
        }
    
    /* End user code. Do not edit comment generated here */
    }
    /* Start user code for other. Do not edit comment generated here */
    
    void my_irq4_callback(void *pdata)
    {
        INTERNAL_NOT_USED( pdata );
    
        BaseType_t sHigherPriorityTaskWoken = pdFALSE;
    
        xSemaphoreGiveFromISR( semaphore_handle_SW1_PUSH, &sHigherPriorityTaskWoken );
        portYIELD_FROM_ISR( sHigherPriorityTaskWoken );
    }
    
    /* End user code. Do not edit comment generated here */
    


    src/frtos_skeleton/task_CONIO.c
    task_CONIO_c_20190918.txt
    #include "task_function.h"
    /* Start user code for import. Do not edit comment generated here */
    #include "freertos_start.h"
    #include "platform.h"
    #include "r_sci_rx_if.h"
    #include "r_sci_rx_config.h"
    #include "r_byteq_if.h"
    
    static uint16_t my_sci_rx_length = 0;
    static volatile uint16_t my_sci_rx_count = 0;
    
    static void my_sci_callback(void *pArgs);
    
    /* End user code. Do not edit comment generated here */
    
    void task_CONIO(void * pvParameters)
    {
    /* Start user code for function. Do not edit comment generated here */
    
        INTERNAL_NOT_USED( pvParameters );
    
        sci_err_t   my_sci_err;
        sci_hdl_t   my_sci_handle;
        sci_cfg_t   my_sci_config;
        uint8_t     my_char[3];
    
        my_sci_config.async.baud_rate    = 115200;
        my_sci_config.async.clk_src      = SCI_CLK_INT;
        my_sci_config.async.data_size    = SCI_DATA_8BIT;
        my_sci_config.async.parity_en    = SCI_PARITY_OFF;
        my_sci_config.async.parity_type  = SCI_EVEN_PARITY;
        my_sci_config.async.stop_bits    = SCI_STOPBITS_1;
        my_sci_config.async.int_priority = 3;    // 1=lowest, 15=highest
    
        my_sci_err = R_SCI_Open(SCI_CH1, SCI_MODE_ASYNC, &my_sci_config, my_sci_callback, &my_sci_handle);
        if (SCI_SUCCESS != my_sci_err)
        {
            for(;;); /* TODO: Handle an error */
        }
    
        for (;;)
        {
            taskENTER_CRITICAL(); // or taskDISABLE_INTERRUPTS()
            {
                // FIXME: This is a super ultra tentative code :(
                my_sci_rx_length = 3;
                my_sci_rx_count = 0;
            }
            taskEXIT_CRITICAL(); // or taskENABLE_INTERRUPTS()
            xSemaphoreTake( semaphore_handle_CON_RX_READY, portMAX_DELAY );
    
            my_sci_err = R_SCI_Receive(my_sci_handle, my_char, my_sci_rx_length);
            if (SCI_SUCCESS != my_sci_err)
            {
                for(;;); /* TODO: Handle an error */
            }
    
            my_sci_err = R_SCI_Send(my_sci_handle, my_char, my_sci_rx_length);
            if (SCI_SUCCESS != my_sci_err)
            {
                for(;;); /* TODO: Handle an error */
            }
        }
    
    /* End user code. Do not edit comment generated here */
    }
    /* Start user code for other. Do not edit comment generated here */
    
    void my_sci_callback(void *pArgs)
    {
    sci_cb_args_t   *args;
    
        args = (sci_cb_args_t *)pArgs;
    
        if (args->event == SCI_EVT_RX_CHAR)
        {
            /* From RXI interrupt; received character data is in args->byte */
            my_sci_rx_count++;
            if (my_sci_rx_count == my_sci_rx_length)
            {
                BaseType_t sHigherPriorityTaskWoken = pdFALSE;
    
                xSemaphoreGiveFromISR( semaphore_handle_CON_RX_READY, &sHigherPriorityTaskWoken );
                portYIELD_FROM_ISR( sHigherPriorityTaskWoken );
            }
            else if (my_sci_rx_count > my_sci_rx_length)
            {
                /* Prevent from doing xSemaphoreGiveFromISR() more than once */
                /* Nothing to do */
            }
        }
    #if SCI_CFG_CH1_DATA_MATCH_INCLUDED
        else if (args->event == SCI_EVT_RX_CHAR_MATCH)
        {
            /* From RXI interrupt; received match character data is in args->byte */
            nop();
        }
    #endif
    #if SCI_CFG_TEI_INCLUDED
        else if (args->event == SCI_EVT_TEI)
        {
            /* From TEI interrupt; transmitter is idle
               Possibly disable external transceiver here */
            nop();
        }
    #endif
        else if (args->event == SCI_EVT_RXBUF_OVFL)
        {
            /* From RXI interrupt; rx queue is full; 'lost' data is in args->byte
               You will need to increase buffer size or reduce baud rate */
            nop();
        }
        else if (args->event == SCI_EVT_OVFL_ERR)
        {
            /* From receiver overflow error interrupt; error data is in args->byte
               Error condition is cleared in calling interrupt routine */
            nop();
        }
        else if (args->event == SCI_EVT_FRAMING_ERR)
        {
            /* From receiver framing error interrupt; error data is in args->byte
               Error condition is cleared in calling interrupt routine */
            nop();
        }
        else if (args->event == SCI_EVT_PARITY_ERR)
        {
            /* From receiver parity error interrupt; error data is in args->byte
               Error condition is cleared in calling interrupt routine */
            nop();
        }
    }
    
    /* End user code. Do not edit comment generated here */
    

     

Children
No Data