Arduinoでタスク xTaskCreate()を使う
経緯
前回の記事で、WindowsでFreeRTOSを動かして、Taskの理解を深めたが、今回は、Arduino IDE でTaskを使い、ESP32で動作確認する
といっても、今までも、深く考えずに、xTaskCreate()を使ってきた
突如、登場する、他と命名則が異なる xTaskCreate() という関数に怯えていたが
FreeRTOSの理解を深めたことで、恐怖心はなくなった
xが何を示しているのか、
Create Task という順番ではなく、Task Createという順番なのかについては、
以下の記事で書いた
試してみたこと
1秒に1回、loop()関数で、LEDを点灯させる、シリアルに出力する
3秒に1回、Taskでシリアルに出力する
シリアルモニターで以下のように、3回loopが表示された後に、1回taskが表示されることを確認
Serial.print()がスレッドセーフなのかは確認できていないが、期待通り動いてくれた
21:39:50.112 -> loop
21:39:51.152 -> loop
21:39:52.190 -> loop
21:39:52.494 -> task
21:39:53.266 -> loop
21:39:54.307 -> loop
21:39:55.350 -> loop
21:39:55.518 -> task
実際のコード全文
#define LED_BUILTIN 2
#define INTERVAL_LOOP 1000
#define INTERVAL_TASK 3000
void setup() {
Serial.begin(115200);
Serial.println("setup");
pinMode (LED_BUILTIN, OUTPUT);
xTaskCreate(my_task, "my_task", 2048, NULL, 1, NULL);
}
void loop() {
Serial.println("loop");
analogWrite(LED_BUILTIN, 30);
delay(50);
analogWrite(LED_BUILTIN, 0);
delay(INTERVAL_LOOP);
}
void my_task(void *arg) {
while (1) {
Serial.println("task");
vTaskDelay(INTERVAL_TASK / portTICK_RATE_MS);
}
}
xTaskCreate()関数の引数と戻り値
pvTaskCode: タスクのエントリーの関数のポインタ
pcName : デバッグ用に使う名前(カーネル側では利用しない)
usStackDepth: タスクがスタック領域で使う容量(スタックが32ビットの場合、400を設定すると、 1600 bytesが割り当てられる)
pvParameters: タスクのエントリーの関数に渡す変数へのポインタ、使わないときはNULLにしてよい
uxPriority: タスクの優先順位
pxCreatedTask: タスクを操作するための変数(タスクを終了するときなどに使う)、使わないときはNULLにしてよい
戻り値: 成功するとpdPASSが返り、失敗するとerrCOULD_NOT_ALLOCATE_REQUIRED_MEMORYが返る
BaseType_t xTaskCreate( TaskFunction_t pvTaskCode,
const char * const pcName,
configSTACK_DEPTH_TYPE usStackDepth,
void *pvParameters,
UBaseType_t uxPriority,
TaskHandle_t *pxCreatedTask
);
参考にしたサイト
気づいたこと
Arduinoのフレームワークを使って、タスクを使いときは、vTaskStartScheduler()を実行する必要がない
フレームワーク側でタスク関連の処理をしてくれていると推測
analogWrite()をloop()とmy_task()の両方で操作しようとすると正しく動作しない
スレッドセーフなのではないと思われるので、セマフォなどを使う必要がありそう
M5 Stick Cの参考コードを見ると、何もしていないloop()関数で、 `vTaskDelay(1000 / portTICK_RATE_MS);` と書いている
そうしないと、メインタスクが、CPUサイクルの半分を消費することになると書かれている
loop()を使わないときは注意する
Arduino IDEでは、includeなどが不要で、簡単に実装できる一方で、隠蔽されたことにより、逆に混乱することもある
ESP IDFで実験することも検討する
次回
Simulatorの簡単なサンプルに含まれていなかったイベント関連の処理をFreeRTOS Windows Simulatorで確認してみる
この記事が気に入ったらサポートをしてみませんか?