如果未启用 CONFIG_SPIRAM,ESP32-S3-WROOM-1-N8R2 模组中集成的 2MB 片内 PSRAM 在工程运行期间会完全闲置,不会被系统或应用代码使用。下面从「底层机制」「代码影响」「例外场景」三个维度讲清楚:
一、核心机制:CONFIG_SPIRAM 是 PSRAM 的 “总开关”
ESP-IDF 中,CONFIG_SPIRAM 控制的是PSRAM 的初始化和系统整合—— 未启用时,系统启动阶段会跳过 PSRAM 的初始化流程:
- 硬件层面:PSRAM(片内)的时钟、通信总线不会被配置,处于 “断电 / 闲置” 状态;
- 系统层面:PSRAM 不会被加入 ESP-IDF 的堆内存管理体系(
heap_caps),malloc/calloc/new等内存分配接口不会分配到 PSRAM; - API 层面:所有 PSRAM 相关 API(如
esp_psram_get_size()、heap_caps_malloc(size, MALLOC_CAP_SPIRAM))会返回 “0” 或 “NULL”,无法访问 PSRAM。
二、对工程代码的具体影响
1. 条件编译代码块直接跳过
你代码中 #if CONFIG_SPIRAM 包裹的逻辑会被编译器完全忽略,不会生成任何指令:
#if CONFIG_SPIRAM // 未启用时,这段代码不会编译进固件
size_t psram_size_mb = esp_psram_get_size() / 1024 / 1024;
lv_image_cache_resize(2 * 1024 * 1024, true);
#endif
即使手动调用 esp_psram_get_size()(比如去掉条件编译),返回值也是 0,无法获取 PSRAM 容量。
2. 系统堆仅使用片内 SRAM
ESP32-S3 的片内 SRAM 分为:
- DTCM(128KB,CPU 高速访问);
- IRAM0(320KB)、DRAM0(256KB); 未启用 PSRAM 时,系统堆仅从这些片内 SRAM 中分配,所有内存操作(包括 LVGL、网络缓存、应用数据)都局限在片内 RAM,PSRAM 完全不参与。
3. 即使手动访问也会失败
若尝试绕过 CONFIG_SPIRAM 直接访问 PSRAM 物理地址,会触发硬件异常(如总线错误),因为 PSRAM 未被初始化,地址映射无效。
三、唯一例外:芯片硬件层面的 “被动存在”
未启用 CONFIG_SPIRAM 时,PSRAM 仅在硬件物理层面存在,但:
- 不会消耗额外功耗(ESP32-S3 会自动断电未初始化的片内 PSRAM);
- 不会影响系统运行(仅相当于 “闲置的硬件资源”);
- 不会被任何 ESP-IDF 组件(LWIP、NVS、LVGL 等)使用 —— 所有组件都会优先使用片内 RAM,仅在
CONFIG_SPIRAM启用且配置了 “优先 PSRAM” 时,才会分配 PSRAM。
四、补充:启用 / 未启用的核心差异对比
| 场景 | 启用 CONFIG_SPIRAM | 未启用 CONFIG_SPIRAM |
|---|---|---|
| PSRAM 初始化 | 系统启动时初始化,加入堆管理 | 跳过初始化,PSRAM 闲置 |
| 内存分配 | malloc/heap_caps 可分配 PSRAM | 仅分配片内 SRAM |
esp_psram_get_size() | 返回实际容量(2MB) | 返回 0 |
| LVGL 缓存 | 可分配到 PSRAM(如你代码中的逻辑) | 只能分配到片内 SRAM |
| 功耗 | 略高(PSRAM 工作) | 略低(PSRAM 断电) |
| 可用内存上限 | 片内 SRAM + 2MB PSRAM | 仅片内 SRAM |
总结
核心结论:
- 未启用
CONFIG_SPIRAM时,ESP32-S3-WROOM-1-N8R2 的 2MB 片内 PSRAM 在工程运行期间完全闲置,无任何代码 / 组件会使用它; - 只有启用
CONFIG_SPIRAM,系统才会初始化 PSRAM 并将其整合到内存管理中,代码才能通过 ESP-IDF 接口访问 / 使用 PSRAM; - 若工程内存需求小(如无 LVGL 大图缓存、无大量网络数据处理),未启用 PSRAM 也能正常运行,仅可用内存上限降低为片内 SRAM 容量。