ESP32のマルチタスクを使う時に無限ループしない場合はvTaskDelete(NULL)が必要
これで1時間溶かしたので怒りのメモです。
環境はArduino core for the ESP32。
メインループをブロッキングしたくない場合、xTaskCreatePinnedToCoreを使ってタスクに処理を逃がすことができる
しかしこのコードは実行時にCore 0 panic'ed (IllegalInstruction). Exception was unhandled.と言われパニックで落ちる
スタックトレースをデコードして見てみても原因がさっぱり分からない
code: arduino
void blinkLED(){
xTaskCreatePinnedToCore(blinkLEDTask, "blinkLEDTask", 4096, NULL, 2, NULL, 0);
}
void blinkLEDTask(void* param){
M5.dis.drawpix(0, 0x000000);
delay(100);
M5.dis.drawpix(0, color);
delay(100);
M5.dis.drawpix(0, 0x000000);
delay(100);
M5.dis.drawpix(0, color);
}
タスクの終了時にvTaskDeleteを呼び出してタスクを閉じる必要がある
つまりこう
code: arduino
void blinkLEDTask(void* param){
M5.dis.drawpix(0, 0x000000);
delay(100);
M5.dis.drawpix(0, color);
delay(100);
M5.dis.drawpix(0, 0x000000);
delay(100);
M5.dis.drawpix(0, color);
vTaskDelete(NULL);
}
というのがxTaskCreatePinnedToCoreを使っている記事に載っていなかった
どこの記事でもタスク内でwhite(true)の無限ループをしていて、使い捨てしているものが無かった
xTaskCreatePinnedToCore 終了でググったらこのツイートが出てきて、vTaskDelete(null)を最後に呼び出すようにしたら解決した
@lovyan03: xTaskCreatePinnedToCore で作ったタスクは
vTaskDeleteで終了させることができる。
Create時点の引数でTaskHandle_t型の変数の参照を渡してハンドルを取得し、Delete時にハンドルを渡せばよい。
なるほど。
https://t.co/5g20yE6UHi
改めてEspressifの公式ドキュメントを見てみたら書いてあった
https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/fatal-errors.html#illegal-instr-msg
FreeRTOS task function has returned. In FreeRTOS, if a task function needs to terminate, it should call vTaskDelete() and delete itself, instead of returning.
自分の愚かさを確認したというのが今回のオチです。公式ドキュメントをちゃんと読みましょう。
#2022Aug