PR 記事には広告が含まれています
スポンサーリンク
Translate

ESP32-WROVER-Bで4MBもの広大なメモリ空間を手にいれる

スポンサーリンク

ESP32の機能はそのままに、さらに8MBのPSRAM(擬似SRAM)が追加で内蔵してある、ESP32-WROVER-Bを購入しました。そこで、Arduino IDEで実際にメモリにアクセスできるのか、試してみました。

スポンサーリンク

ESP32-WROVERシリーズ

左が普通のESP32(ESP-WROOM-32)が載ったESP32-DevKitCで、右側がESP32-WROVER-Bが載ったESP32-DevKitC-VBです。ESP32-WROVER-Bは、銀色のパッケージが縦長になっています。縦長になった分、その中に8MBのPSRAMが追加されて入っているのでしょう。

パッケージは縦長になりましたが、ピンの数は同じで、普通のESP32と全く同じように機能します。

ESP32-WROVER シリーズには、他にも種類があり

  • ESP32-WROVER:1.8Vで動作するタイプ
  • ESP32-WROVER-I:1.8Vで動作し、アンテナが外付けのタイプ
  • ESP32-WROVER-B:3.3Vで動作するタイプ
  • ESP32-WROVER-IB:3.3Vで動作し、アンテナが外付けのタイプ

の4種類があります。さらにそれぞれ、フラッシュメモリの容量が4MB、8MB、16MBというバリエーションがあります。

USBインターフェースがついたESP32-DevKitC-VBには、フラッシュ容量が4MBのESP32-WROVER-Bが載っています。

スポンサーリンク

ArduinoでPSRAMの容量をチェック

ボードの追加

プログラムを書く前に、ボードの設定をします。[ツール]->[ボード]->[ESP32 Wrover Module]を選択します。

パラメータをチェック

ESP32のパラメータを、シリアルへ出力するプログラムです。

void setup() {
  Serial.begin(115200);
  Serial.printf("Internal Total heap %d, internal Free Heap %d\n", ESP.getHeapSize(), ESP.getFreeHeap());
  Serial.printf("SPIRam Total heap %d, SPIRam Free Heap %d\n", ESP.getPsramSize(), ESP.getFreePsram());
  Serial.printf("Flash Size %d, Flash Speed %d\n", ESP.getFlashChipSize(), ESP.getFlashChipSpeed());
  Serial.printf("ChipRevision %d, Cpu Freq %d, SDK Version %s\n", ESP.getChipRevision(), ESP.getCpuFreqMHz(), ESP.getSdkVersion());
}

void loop() {
}

プログラムを書き込みます。実行されると、シリアルモニターにパラメータが表示されます。

Internal Total heap 379064, internal Free Heap 353776
SPIRam Total heap 4194252, SPIRam Free Heap 4194252
Flash Size 4194304, Flash Speed 80000000
ChipRevision 1, Cpu Freq 240, SDK Version v3.2.3-14-gd3e562907
PSRAMの空き容量は4194252バイト。約4MBです。8MBのPSRAMが載っているのですが、実はCPUから直接アクセスできるメモリ空間が4MB分しかないため、Arduinoではこれだけしか利用することができません。
ESP-IDFという開発環境では、himem APIを使うことで8MBの空間にアクセスできるようになるようです。

書き込みチェック

それでは、実際にメモリを確保して正しく書き込めるのか、チェックしてみたいと思います。

PSRAMのメモリを利用するには、ps_malloc()か、ps_calloc()で、必要なメモリサイズを確保してから利用します。

  • ps_malloc( バイト数 ):バイト単位で利用したい容量を確保できます
  • ps_calloc( 配列数 , 型のバイト数 ):intやdoubleなど、型の配列に必要な容量を確保します。また、配列は0で初期化してくれます。

今回はcallocで、PSRAMのメモリを確保してみます。

void setup() {
  Serial.begin(115200);
  Serial.printf("Internal Total heap %d, internal Free Heap %d\n", ESP.getHeapSize(), ESP.getFreeHeap());
  Serial.printf("SPIRam Total heap %d, SPIRam Free Heap %d\n", ESP.getPsramSize(), ESP.getFreePsram());
  Serial.printf("Flash Size %d, Flash Speed %d\n", ESP.getFlashChipSize(), ESP.getFlashChipSpeed());
  Serial.printf("ChipRevision %d, Cpu Freq %d, SDK Version %s\n", ESP.getChipRevision(), ESP.getCpuFreqMHz(), ESP.getSdkVersion());
  Serial.println("");

  //SPRAM全ての容量を確保
  int memMax = ESP.getFreePsram();
  char *p = (char*) ps_calloc( memMax , sizeof(char) );
  if (p == NULL) {
    Serial.println("確保できず");
  }

  //1バイト毎に値が書き込めるかチェック
  int i = 0;
  while ( i < memMax )
  {
    p[i] = (char)i; //値を書き込む
    if ( p[i] != (char)i )  //値が合っているかチェック
    {
      Serial.printf("write error at %d\n", i);
      i--;
      break;
    }
    i++;
  }

  Serial.printf("%d bytes check Ok\n", i);
  
  free(p); //メモリの解放
}

void loop() {
}

ps_callocでchar型の配列で、全ての空き容量を確保します。そして、全ての配列に対して数字を書き込み、読み出した値が書き込んだ値と同じかどうかチェックします。

実行結果がこちらです。

Internal Total heap 378940, internal Free Heap 353652
SPIRam Total heap 4194252, SPIRam Free Heap 4194252
Flash Size 4194304, Flash Speed 80000000
ChipRevision 1, Cpu Freq 240, SDK Version v3.2.3-14-gd3e562907

4194252 bytes check Ok

4192452バイトの空き領域を確保して、4192452バイトOKでした。つまり確保できた約4MBのメモリ空間に対して、値が正しく書き込めることがわかりました。

ESP32では確保できるサイズが、せいぜい100kB程度だったので、4MBはとても広いメモリ空間です。これで、画像などの大きなデータもESP32で扱えるようになりますね。