見出し画像

twESP32Sensor開発:再起動を繰り返す問題の犯人はボードとstd::stringの組み合わせだった

今朝は4時におきました。助手の猫さんは寝室のドアの前で待っていました。

昨日発見したESP32がパニックで再起動を繰り返す問題を調べることにしました。どうやら問題は

のボードだけで発生しています。れいのLEDがついていないボードです。
去年買った

はLEDもついていて再起動も発生しません。M5StickC Plus2

も大丈夫です。
ボードのメモリー情報をモニターで表示してみると問題の発生するほうは

2024-02-29T04:12:10+09:00 monitor count=4395 cpu=99.91 mem=85.24 total=220676 free=32568 min=14456 psram=0

発生しないほうは

2024-02-29T04:56:11+09:00 monitor count=61875 cpu=99.91 mem=83.92 total=220372 free=35444 min=10712 psram=4187463

です。PSRAMというメモリに違いがあります。問題あるほうには付いていないようです。Amazonの製品説明にはSRAM 520KBとなっていますが?
M5StickにもPSRAMがついていました。

ボードのせいにして、このまま調査終了でもよいのですが、気になるのでもう少し調べることにしました。
問題発生した時のESP32のStackトレース

をみるとstd::stringのメモリを確保する時の処理で例外が発生しているのがわかります。そこで

void setup() {
  Serial.begin(115200);
  std::string r = "";

  for(int i = 0;i < 1024 * 1024;i ++) {
    if (i % 100 == 0) {
      uint32_t free = ESP.getFreeHeap();
      uint32_t total = ESP.getHeapSize();
      uint32_t min = ESP.getMinFreeHeap();
      uint32_t psram = ESP.getFreePsram();
      uint32_t mha = ESP.getMaxAllocHeap();
      Serial.printf("i=%d total=%d free=%d min=%d psram=%d mha=%d\n",i,total,free,min,psram,mha);
    }
    r += std::string(" ");
  }
}

のようなテストスケッチを作って試してみました。
問題のあるボードでは再起動を繰り返す現象が再現しました。問題のないボードでは発生しません。
試しに、std::stringをArduinoのString型に代えてみました。

void setup() {
  Serial.begin(115200);
  String r = "";

  for(int i = 0;i < 1024 * 1024;i ++) {
    if (i % 100 == 0) {
      uint32_t free = ESP.getFreeHeap();
      uint32_t total = ESP.getHeapSize();
      uint32_t min = ESP.getMinFreeHeap();
      uint32_t psram = ESP.getFreePsram();
      uint32_t mha = ESP.getMaxAllocHeap();
      Serial.printf("i=%d total=%d free=%d min=%d psram=%d mha=%d\n",i,total,free,min,psram,mha);
    }
    r += String(" ");
  }

}

こちらは、どちらのボードも問題が発生しません。
どうやら、PSRAMのないボードとstd::stringの組み合わせがよくないようです。
PSRAMのないボードに対応するためstd::stringをStringに変更することにしました。けっこう沢山あるので、時間がかかりそです。

明日に続く

開発のための諸経費(機材、Appleの開発者、サーバー運用)に利用します。 ソフトウェアのマニュアルをnoteの記事で提供しています。 サポートによりnoteの運営にも貢献できるのでよろしくお願います。