ESP32模块对内部RAM的设计做了内存扩展。您可以通过寻址高达4MB的外部SPI RAM内存来进一步扩展它。在本文中,探讨如何在项目中使用PSRAM,针对ESP32-WROVER模块进行特别的讨论。

关键问题:

  1. 如何确保PSRAM在应用程序代码中可用?
  2. 如何分配和使用PSRAM内存?
  3. ESP32的PSRAM容量限制为4MB,即使某些模块带有8MB芯片。

ESP-WROVER:8MB PSRAM?

esp32 psram作用 esp32 psram arduino_前端

  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软件就能突破的限制。

ESP32有多少PSRAM?

那么,这个外部PSRAM有多少?如何使用?在开始之前,让我们确保我们的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() {}

请注意,我使用日志记录宏日志log_d(..)这允许我们稍后禁用日志输出。如果我们在Arduino IDE中使用工具菜单中的以下设置运行此代码。特别要确保将“Core Debug Level”设置为“Verbose”。

esp32 psram作用 esp32 psram arduino_ESP32_02

运行代码会在串行监控信息如下:

[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

请注意,最后一行需要查看日志log_d(..)输出。但为什么我们没有看到PSRAM?事实证明,我们需要手动启用PSRAM配置。我们必须通过向platformio.ini添加build_flags配置项来实现这一点:

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相关信息参考:片外 RAM - ESP32 - — ESP-IDF 编程指南 latest 文档 (espressif.com)

如何使用PSRAM?

  在前面一段中,我们讨论了如何确保PSRAM可用。现在我们要看看如何使用它。根据Espressif,有四种使用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是否可用,而不是检查可用外部内存的大小。

  1. 参考原文:ESP32 - How To Use PSRAM • ThingPulse