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() { }
プログラムを書き込みます。実行されると、シリアルモニターにパラメータが表示されます。
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のメモリを利用するには、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で扱えるようになりますね。
コメント