ESP32的内部RAM的设计做了内存扩展。您可以通过寻址高达4MB的外部SPI RAM内存来进一步扩展它。在本文中,探讨如何在项目中使用PSRAM,针对ESP32-WROVER模块进行特别的讨论。
关键问题:
- 如何确保PSRAM在应用程序代码中可用?
- 如何分配PSRAM内存?
- ESP32的PSRAM容量限制为4MB,即使某些模块带有8MB芯片。
ESP-WROVER:8MB PSRAM?
ESP32的制造商Espressif销售一个名为ESP-WROVER的模块,它的数据手册中标明有8MB的PSRAM。PSRAM代表伪静态RAM。该模块可能配有一个8MB的外部PSRAM芯片,但事实上,您(目前?)只能在应用程序中使用较低的4MB。实事求是来讲,4MB RAM对于微控制器来说确实是够大的,但8MB的广告有点误导。也许硬件有8MB,但是软件只能利用4MB.
如果我们相信:Espressif对外部PSRAM的4MB限制是基于硬件限制而不是ESP-IDF框架中的软件限制。虽然有些应用需要大量的内存,但是ESP32最多可以使用4 MB的外部SPI RAM内存。这听起来更像是一个硬件限制,而不是一个修改SDK软件就能突破的限制。
ESP-WROVER:8MB PSRAM?
那么,如何使用这个外部RAM?在开始之前,让我们确保我们的ESP32模块有这个外部PSRAM,并且可以从我们的代码中寻址。ESP32/Arduino平台提供了两种方法来确定您总共有多少RAM以及可以使用多少RAM。
#include <Arduino.h>void setup() {log_d("Total heap: %d", ESP.getHeapSize());log_d("Free heap: %d", ESP.getFreeHeap());log_d("Total PSRAM: %d", ESP.getPsramSize());log_d("Free PSRAM: %d", ESP.getFreePsram()); }void loop() {}
请注意,我使用日志记录宏日志_(..)这允许我们稍后禁用日志输出。如果我们在Arduino IDE中使用工具菜单中的以下设置运行此代码。特别要确保将“核心调试级别”设置为“详细”。
运行代码会在串行监控信息如下:
[D][esp32-hal-psram.c:47] psramInit(): PSRAM enabled [D][PSRAMTestArduino.ino:4] setup(): Total heap: 393356 [D][PSRAMTestArduino.ino:5] setup(): Free heap: 367948 [D][PSRAMTestArduino.ino:6] setup(): Total PSRAM: 4194252 [D][PSRAMTestArduino.ino:7] setup(): Free PSRAM: 4194252
结果符合预期!日志输出告诉我们PSRAM已激活,并且有4MB的PSRAM可用。如果我们在Platformio IDE中运行相同的代码,我们会得到以下结果:
[D][main.cpp:4] setup(): Total heap: 390484 [D][main.cpp:5] setup(): Free heap: 365140 [D][main.cpp:6] setup(): Total PSRAM: 0 [D][main.cpp:7] setup(): Free PSRAM: 0
嗯,奇怪,不是吗?也许选错了开发板类型。这在platformio.ini中配置:
[env:esp-wrover-kit] platform = espressif32 board = esp-wrover-kit framework = arduino monitor_speed = 115200 upload_speed = 921600 build_flags = -DCORE_DEBUG_LEVEL=5
请注意,最后一行需要查看日志_(..)输出。但为什么我们没有看到PSRAM?事实证明,我们需要手动启用PSRAM配置。我们必须通过向platformio.ini添加构建标志来实现这一点:
build_flags = -DCORE_DEBUG_LEVEL=5 -DBOARD_HAS_PSRAM -mfix-esp32-psram-cache-issue
-DBOARD_HAS_PSRAM启用PSRAM支持和-mfix-esp32-psram-cache-issue是一种解决方案,用于在启用PSRAM时可能导致板崩溃的代码序列。阅读有关此的更多信息在这里.
如何使用PSRAM?
在最后一段中,我们看到了如何确保PSRAM可用。现在我们要看看如何使用它。根据浓缩咖啡手册,有四种使用PSRAM的方法。在这篇博客文章中,我们只看一种。
内部RAM已经相当大了。因此,您很可能会使用外部内存来分配相对较大的缓冲区。为此,我们可以使用ps_malloc()和free()释放内存。下面的代码是内存分配演示:
#include <Arduino.h> void logMemory() { log_d("Used PSRAM: %d", ESP.getPsramSize() - ESP.getFreePsram()); } void setup() { logMemory(); byte* psdRamBuffer = (byte*)ps_malloc(500000); logMemory(); free(psdRamBuffer); logMemory(); } void loop(){}
运行代码会在串行控制台上显示以下内容:
[D][esp32-hal-psram.c:47] psramInit(): PSRAM enabled [D][main.cpp:4] logMemory(): Used PSRAM: 0 [D][main.cpp:4] logMemory(): Used PSRAM: 500000 [D][main.cpp:4] logMemory(): Used PSRAM: 0
恭喜,您刚刚成功地在外部PSRAM中分配了内存!
关于PSRAM的更多信息
如果您想了解更多有关PSRAM的信息,打开ESP32/Arduino平台下的esp32-hal-psram.c文件。在这个文件里,可以看到下面的函数:
bool psramFound(); void *ps_malloc(size_t size); void *ps_calloc(size_t n, size_t size); void *ps_realloc(void *ptr, size_t size);
实际应用中,可以使用psramFound()检查伪ram是否可用,而不是检查可用外部内存的大小。
-
参考原文:ESP32 - How To Use PSRAM • ThingPulse