はじめに
筆者、最近FreeRTOSを触る予定ができたため、その練習を兼ねてここから使い方を残していければと思う。また、RenesasのRXファミリを使用したいため、RX72N Envision Kitを使用して、実装を進めていく予定だ。
最終目標はFreeRTOSを前提に、USBやEthernet、Wi-Fiなどの通信系、SDカードやUSBメモリなど、排他処理等を必要とした状態での良い(?)設計の習得を目指す。
前提知識
RXファミリでのプロジェクト作成、クロックやコンポーネントの設定方法を知っているものとします。また、タイマ割込みやハードウェア割込みによるシーケンス周期処理等の知識が前提としてあるものとします。
本投稿では
手始めに、RTOSの導入方法とLチカのみを行う。500ms毎にblinkする。
環境
FreeRTOSを学習するにあたって、下記の環境を準備した。
- IDE:e2studio
- ボード:RX72N Envision Kit
- コンパイラ:CC-RX(ツールチェーン Renesas CC-RX v3.07.00)
作業開始
1. プロジェクトの作成
Toolchain Settings で RTOS を FreeRTOS (kernel only) にする。(今回はLチカのみなので、IoT関連のライブラリを必要としないはず。)
Device Settings は RX72N Envision Kit を使用するため、下図のような設定となりました。

2. スマートコンフィギュレータの確認
プロジェクトエクスプローラーからスマートコンフィギュレータ(.scfg)のファイルを開くと、下図のように、コンポーネント->FreeRTOS_Object を選択する。
このページでFreeRTOSのタスクやキュー、セマフォなどを設定するようだ。

3. Lチカ用タスクの追加と設定
Tasks タブを開くと下図が表示される。

左側の+ボタンを押下することで、新規タスクを作成できる。(非常に簡単だ…)
Lチカ目的なので、Task Code と Task Name に led_task という名前を付けてみる。
作成後に「プロジェクトのビルド」か「コードの生成」を実行することにより、src/frtos_skeleton/led_task.cが生成される。

次にこのファイルを開いて、処理を作っていきます。
4. Lチカの処理を書く
必要なヘッダファイルをインクルードし、Envision Kit のユーザLEDであるP40をトグルする処理を書く。
#include "task_function.h"
/* Start user code for import. Do not edit comment generated here */
#include "FreeRTOS.h"
#include "task.h"
#include "platform.h"
/* End user code. Do not edit comment generated here */
void led_task(void * pvParameters)
{
/* Start user code for function. Do not edit comment generated here */
TickType_t xLastWakeTime; // 最後にタスクが実行された時刻を記録する変数
const TickType_t xPeriod = pdMS_TO_TICKS(500); // 周期を500ミリ秒に設定
xLastWakeTime = xTaskGetTickCount();
while(1)
{
// xPeriodの間隔でタスクが実行されるように待機
// 次回の実行時刻は、xLastWakeTimeにxPeriodを加えた時刻になる
vTaskDelayUntil( &xLastWakeTime, xPeriod );
// ここに周期的に実行したい処理を記述
PORT4.PODR.BIT.B0 = !PORT4.PODR.BIT.B0; // P40 を 500ms 毎に反転
}
/* 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 */
各行説明
xLastWakeTime = xTaskGetTickCount();
ここでは、タスク生成時の時刻を保持しておく。
vTaskDelayUntil( &xLastWakeTime, xPeriod );
while文の繰返し周期をここで決めている。
xLastWakeTime に代入されている時刻を基準に、 xPeriod ミリ秒後、次回の周期を実行するようにする。xLastWakeTime は更新される。
第2引数に指定する秒数は configTICK_RATE_HZ で決まる。デフォルトは1000 なので、1ミリ秒単位で指定。configTICK_RATE_HZ はコンフィギュレータのコンポーネント、FreeRTOS_Kernelで変更できる。
PORT4.PODR.BIT.B0 = !PORT4.PODR.BIT.B0;
LEDポートのHigh/Lowをトグルする。
これでデバッグを実行するとLEDが光った!

なんか比較的簡単にできたな!?
デバッグ時、公式ドキュメントの通りにデバッグ構成を変更するとデバッグは実行できますが、クロックの設定ができていないので、LEDの点滅間隔が500msよりも長くなってしまうことがある。スマートコンフィギュレータのクロックタブでメインクロックの設定も変更を忘れずに!
次回
SW2の状態を取得するSW2_TASKタスクを作り、タスク間通信により、LED_TASKに状態を送ることでLEDをOnOffを制御するような処理にしたい。
おそらくFreeRTOSのStream BuffersかMessaage Buffersを利用することになるだろうと思っている。
どうやらQueueを使用するみたいである。