[英]How to extend ESP32 heap size?
我正在编写有关在 TFT 屏幕上从 SDCard 播放 gif 的代码,因此我创建了一个数组来放置 gif 文件。 (使用 Nodemcu-32s 4MB)
#include<TFT_eSPI.h>
#include<SPI.h>
#include<AnimatedGIF.h>
TFT_eSPI tft;
AnimatedGIF gif;
uint8_t *gifArray;
int gifArrayLen;
void setup(){
tft.init();
tft.setRotation(2);
tft.fillScreen(TFT_BLACK);
File fgif=SD.open("/test.gif",FILE_READ);
gifArrayLen=fgif.size();
gifArray=(uint8_t *)malloc(gifArrayLen);
for(int i=0;i<gifArrayLen;i++) gifArray[i]=fgif.read();
fgif.close();
}
void loop(){
tft.startWrite();
gif.open(gifArray,gifArrayLen*sizeof(uint8_t),GIFDraw);
while(gif.playFrame(true,NULL)) yield();
gif.close();
tft.endWrite();
}
但是如果 gif size > 131KB,就会触发这样的致命错误。
Guru Meditation Error: Core 1 panic'ed (StoreProhibited). Exception was unhandled.
在 malloc 数组之后,当我在其上设置一个值时,它触发了。
我发现一些论坛说这是因为它超过了 FreeRTOS 堆大小。
我可以扩展堆大小或使用其他存储方法来替换它吗?
NodeMCU 中的“4MB”指的是 flash 的大小, ESP32上的 RAM 大小固定为 512KB,其中大约 200KB 用于 IRAM 缓存/代码部分,剩下大约 320KB 给程序 memory,其中一半用于动态分配。
来自文档堆 Memory - 可用堆:
由于技术限制,最大静态分配的 DRAM 使用量为 160KB。 剩余的 160KB(总共 320KB 的 DRAM)只能在运行时分配为堆。
有一种方法可以通过 SPI 连接更多 RAM,但速度会很慢。 您可能想要研究具有更多 RAM 的更大 SoC。
堆是 memory 的池,可供您的程序分配存储空间。
您使用的是 ESP32,这是一个具有少量 RAM(大约 400KB)的小型 CPU。
您不能扩展 ESP32 上的堆。 与具有虚拟 memory 的 Linux 不同,它没有任何可扩展的内容。
但是,您可以以外部 PSRAM 的形式添加额外的存储 - 通过 SPI 访问的额外 RAM。 PSRAM 将比内部 RAM 慢,并且对其使用有一些限制(例如,调用堆栈不能存在于 PSRAM 中,某些 DMA 缓冲区不能位于那里)。
ESP32 的制造商 Espressif 已经记录了如何将 PSRAM 与 ESP32 一起使用。
您通常(可能专门)会发现 ESP32 板上内置了 PSRAM,因此如果您使用的 ESP32 模块还没有,您将需要一个新的 ESP32 模块。
正如其他人指出的那样,您可以通过过度分配和释放 memory 来人为地导致堆中可用的 memory 减少,从而使堆碎片化,以便没有大块仍然可用。 这称为堆碎片,已在 Stack Overflow 和其他 web 站点上进行了大量讨论。
您可以使用 IRAM 为堆添加更多空间。 通常,DRAM 来自 SRAM1 (128 KB) 和 SRAM2 (200 KB),总共 328 KB。 但由于 ROM 在 RAM 中使用 8 KB 用于其 function,因此总可用 DRAM 只有 320 KB。 IRAM(来自 SRAM0)通常用于代码而不是数据。 但由于并非所有空间都用于代码,因此剩余字节可用于数据。 如果您使用 arduino 框架,通常会有大约 72 KB 可用作堆。 但是访问必须是32位对齐的,比如int数组或者指针。 有关详细信息,请参阅此链接。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.