基本ライブラリ
デジタルIO
アナログIO
拡張IO
時間
数学
三角関数
乱数
ビットバイト操作
割り込み
シリアル通信
標準ライブラリ
Ethernet
サーボモーター
ステッピングモーター
キャラクタ液晶表示
SPI通信
I2C通信(Wire)
SD
SD(File操作)
周期処理(MsTimer2)
時計(RTC)
PPG(パルス生成)
WiFiEsp
ICS(シリアルサーボ)
FreeRTOS Tips
FreeRTOS タスク
タスクの実装は以下のように、戻り値はなく、void型のポインターを引数に取ります。タスクは無限ループとして実装し、終了する場合は明示的にタスクをDeleteします。
void ATaskFunction( void *pvParameters );
void ATaskFunction( void *pvParameters ){
while(1){
// do something
}
}
GR-ROSEはシングルコアのため、同時に一つのタスクしか実行されません。実行しているときの状態を"Running"、実行していないときは複数の状態(State)として、 "Blocked"、 "Ready"、 "Suspended"があります。
タスクは最も優先順位の高いものから実行され、優先順位が同じ場合は順番に実行されます。優先順位が低いタスクを実行中に、優先順位が高いタスクが"Ready"になった場合は、実行するタスクがスイッチされます。
タスクの中でvTaskDelay()やdelay()、あるいはQueueを待つような処理を実行したとき、"Blocked"状態になります。もし優先順位の低いタスクが"Ready"となっていた場合は、"Running"状態になります。
GR-ROSEのSDKでは、優先順位を7段階(0から6)で指定できます。setupやloopが実行されるmainタスクの優先順位は3となっています。以上を踏まえて一つサンプルを掲載します。
#include <Arduino.h>
#include "FreeRTOS.h"
#include "task.h"
void task1(void *pvParameters);
void task6(void *pvParameters);
void setup(){
Serial.begin(9600);
delay(3000); // wait for display serial monitor
xTaskCreate( task1, "TASK1", 512, NULL, 1, NULL );
xTaskCreate( task6, "TASK6", 512, NULL, 6, NULL );
}
void loop(){
static uint32_t ctime = millis();
if((millis() - ctime) > 5000){
delay(1000); // entering Block State
}
}
void task1(void *pvParameters){
while(1){
Serial.println("task1 running");
delay(1000); // entering Blocked State
}
}
void task6(void *pvParameters){
while(1){
Serial.println("task6 running");
delay(1000); // entering Blocked State
}
}
上記のサンプルは優先度1のtask1と、優先度6のtask6を生成しています。それぞれ1秒毎にシリアル出力をするタスクです。5秒経つと、優先度3のloopでdelay()が実行され"Blocked"状態になります。
実行すると以下のようにシリアルモニターに表示されます。setupでtask1とtask6が生成されますが、5秒間はloopよりも優先度が高いtask6のみが実行されます。5秒後はloopでdelay()を実行し、"Blocked"状態になるため、task1も実行されるようになっていることが分かります。
task6 running
task6 running
task6 running
task6 running
task6 running
task6 running
task1 running
task6 running
task1 running
task6 running
task1 running
task6 running
task1 running
タスクをDeleteするサンプルを示します。1秒毎に周期タスクが実行されますが、5回実行したときにvTaskDeleteを実行し、タスクをDeleteしています。タスクは概要に示す通り、HEAPメモリを消費しますので、不要なときはDeleteしましょう。
#include <Arduino.h>
#include "FreeRTOS.h"
#include "task.h"
void periodic(void *pvParameters);
TaskHandle_t periodicHandle = NULL;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
delay(1000);
xTaskCreate(periodic, "PERIODIC", 512, NULL, 2, &periodicHandle);
}
void loop() {
// put your main code here, to run repeatedly:
delay(1);
}
void periodic(void *pvParameters) {
while (1) {
static int count = 0;
Serial.println(count);
delay(1000);
count++;
if(count == 5){
vTaskDelete( periodicHandle );
}
}
}