//Arduino FreeRTOSライブラリをインクルード
#include <Arduino_FreeRTOS.h>
int ledPin = 13;
//タスクのハンドルを格納するための変数を宣言
TaskHandle_t TaskBlink_Handler;
TaskHandle_t TaskSerial_Handler;
//タスクとして実行される関数のプロトタイプ宣言
void TaskBlink( void *pvParameters );
void TaskSerial(void* pvParameters);
void setup() {
Serial.begin(9600);
while (!Serial); //シリアルポートが利用可能になるまで待機する
Serial.println("sで停止、rで再開");
xTaskCreate(
TaskBlink //タスクとして実行する関数
, "Blink" //タスクの名前(デバッグなどに役立つ)
, 128 //タスクに割り当てるスタックサイズ(実行時に使用できるメモリ領域の大きさ)
, NULL //タスクに渡す引数、ここでは使用しないためNULL
, 2 //タスクの優先度、値が大きいほど優先度が高くなる
, &TaskBlink_Handler //タスクのハンドルを格納する変数
);
xTaskCreate(TaskSerial, "Serial", 128, NULL, 1, &TaskSerial_Handler );
vTaskStartScheduler(); //FreeRTOSのスケジューラを開始します。
}
void loop(){
//FreeRTOSを使用する場合タスク内で処理を行う
}
void TaskSerial(void* pvParameters){
(void) pvParameters; //今回は引数を使わないので、この1行は削除しても問題ない
//無限ループになればよいので、while(1)と書いても良い
for (;;){
while(Serial.available()){
switch(Serial.read()){
case 's':
vTaskSuspend(TaskBlink_Handler); //TaskBlinkタスクを中断
Serial.println("TaskBlink Suspend!");
break;
case 'r':
vTaskResume(TaskBlink_Handler); //TaskBlinkタスクを再開
Serial.println("TaskBlink Resume!");
break;
}
vTaskDelay(1);
/*
vTaskDelay(1) はタスクを1ティック分の時間、実行スケジュールから外す。
この間、他のタスクが実行される可能性があり、マルチタスクの環境では重要な役割を果たす。
FreeRTOSのスケジューリング機構を利用して、CPUを他のタスクに渡すために使用される。非ブロッキング。
なぜdelay()ではダメなのか?
delay() は指定されたミリ秒数だけ、CPUが他の処理を行わずに待機する。
この間、他のコードやタスクは実行されないので、ブロッキング動作といえる。
他の動作がブロックされるので、マルチタスクの環境には向いていない。
*/
}
}
}
void TaskBlink(void *pvParameters){
//(void) pvParameters;
pinMode(ledPin, OUTPUT);
while(1){
digitalWrite(ledPin, HIGH);
vTaskDelay( 1000 / portTICK_PERIOD_MS );
/*
vTaskDelayの引数には「遅延する時間」を指定するが、その時間は「システムティック」
システムティックは、FreeRTOSのタイマー割り込みの間隔を表している
portTICK_PERIOD_MSは、1ティックが何ミリ秒に相当するかを表す
デフォルトでは、1ティックが1ミリ秒に設定されている
つまりこの式は「1000ミリ秒 ÷ 1ティック = 1000ティック(ミリ秒)」という意味になる
*/
digitalWrite(ledPin, LOW);
vTaskDelay( 1000 / portTICK_PERIOD_MS );
}
}