ESP32のesp32-hal.h周りのマルチタスクを調べる

M5StickC非公式日本語リファレンスで項目を書くためにesp32-halの項目を調べました。

サンプルコード

void loopTest(void *pvParameters) {
  while (1) {
    Serial.print( xPortGetCoreID() ); // 動作確認用出力
    vPortYield();                     // vPortYield()ではウォッチドッグに影響しない
    yield();                          // yield()ではウォッチドッグに影響しない
    delay(0);                         // 1以上にするとウォッチドッグのリセットがなくなる
    delayMicroseconds(1000000);       // delayMicroseconds()はウォッチドッグとは関係ない
  }
}

void setup() {
  Serial.begin(115200);

  // Core0でタスク起動
  xTaskCreateUniversal(
    loopTest,
    "loopTest0",
    8192,
    NULL,
    1,
    NULL,
    0
  );

  // Core1でタスク起動
  xTaskCreateUniversal(
    loopTest,
    "loopTest1",
    8192,
    NULL,
    1,
    NULL,
    1
  );

  // ウォッチドッグ停止
  //disableCore0WDT();
  //disableCore1WDT();  // 起動直後は有効化されていないのでエラーがでる

  // ウォッチドッグ起動
  //enableCore0WDT();
  //enableCore1WDT();
}

void loop() {
}

解説

他サイトのサンプルですとxTaskCreatePinnedToCore()かxTaskCreate()を使っているケースばかりでした。

ESP32の1.0.2からxTaskCreateUniversal()が増えたようでして、内部でxTaskCreatePinnedToCore()かxTaskCreate()を呼び出しています。

xTaskCreate()はシングルコア用の古い関数で、無効なcore番号を指定すると内部で呼び出されてCore0でタスクが起動していました。

通常はCore1でloop()などが実行されており、ウォッチドッグ は無効です。Core0はウォッチドッグが有効化されており、長時間ブロックしているとハングアップしたとみなされ、リセットが入ります。

リセットを回避する方法はdisableCore0WDT()でウォッチドッグを無効化するか、処理の中で定期的にdelay(1)を呼び出すかが必要です。delay(0)とかyield()では回避できませんでした。

まとめ

リファレンスで関数群が大体モーラできたかと思っていましたが、xTaskとかvPort系の関数が抜けていました。どんどん対象が広がっていきます、、、

コメントする

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)