1. Зачем нужна PSRAM в ESP32
Микроконтроллеры семейства ESP32 имеют сотни килобайт встроенной SRAM, размещённой на том же кристалле, что и CPU, периферия и контроллеры. Для задач вроде:
обработки графики (LVGL, дисплеи),
буферизации аудио,
работы с большими JSON,
сетевых стеков,
ML-моделей,
этого объёма часто недостаточно.
Поэтому архитектура предусматривает подключение внешней PSRAM (Pseudo-Static RAM) — псевдо-статической оперативной памяти, которая расширяет доступный heap.
2. Что такое PSRAM
2.1 Терминология
В документации Espressif используются как взаимозаменяемые:
PSRAM
SPI RAM
SPIRAM
Во всех случаях речь идёт об одном типе внешней памяти.
2.2 Почему «Pseudo-Static»
PSRAM сочетает в себе:
Внутренняя структура: DRAM
Ячейки динамические (как в DRAM)
Требуется refresh
Внешний интерфейс: как у SRAM
Встроенная логика регенерации
CPU работает с ней как с обычной RAM
Внешний контроллер refresh не нужен
Именно поэтому — Pseudo-Static.
3. Аппаратная архитектура доступа к PSRAM
3.1 Подключение
PSRAM подключается:
через SPI / QSPI / OPI
по той же шине, что и Flash
с отдельной линией Chip Select
В модулях типа WROVER чип PSRAM обычно установлен внутри металлического экрана.
В новых сериях возможна:
in-package PSRAM (в одном корпусе с SoC)
но архитектурно она остаётся «внешней»
3.2 Как CPU обращается к PSRAM
Доступ НЕ прямой.
Схема:
CPU → Cache → MMU → SPI → PSRAM
Алгоритм:
CPU обращается к виртуальному адресу.
MMU отображает его в физический адрес PSRAM.
Cache:
cache hit → мгновенно
cache miss → чтение через SPI
В новых сериях используется write-back cache.
3.3 Главное ограничение
PSRAM всегда медленнее внутренней SRAM, потому что:
последовательная шина
работа через кэш
латентность SPI
Следствие: стек задач и DMA-буферы по умолчанию остаются во внутренней памяти.
4. Важные аппаратные ограничения
4.1 Напряжение
PSRAM бывает:
1.8 В
3.3 В
Оно должно совпадать с Flash.
Выбор задаётся:
strapping pins
eFuse
Ошибка может:
отключить память
повредить чип
4.2 DMA
На старых ESP32:
DMA напрямую с PSRAM невозможен
На новых сериях:
возможен
но требует контроля когерентности кэша
4.3 Стек FreeRTOS
По умолчанию:
стек задач → внутренняя RAM
Технически можно разместить в PSRAM (через xTaskCreateStatic), но это не рекомендуется.
5. Особенности разных серий ESP32
5.1 Классический ESP32
QSPI (4 линии)
максимум 4 МБ отображаемого окна
кэш 32 КБ на ядро
при 8 МБ требуется Himem API (bank switching)
Поддерживаются режимы MMU:
Normal
Low-High
Even-Odd
DMA напрямую не работает.
5.2 ESP32-S2
независимые ICache и DCache
до 10.5 МБ виртуального адресного пространства
возможно выполнение кода из PSRAM
настраиваемый размер кэша
5.3 ESP32-S3
Quad / Octal SPI
поддержка XTS-AES
до 32 МБ отображаемого пространства
общий кэш для двух ядер
Octal PSRAM заметно быстрее Quad.
5.4 ESP32-C5 и ESP32-C61
поддержка PSRAM есть
до 32 МБ отображения
доступ через кэш и GDMA
Ранние C-серии (C2, C3, C6) PSRAM не поддерживают.
5.5 ESP32-P4
Наиболее производительная архитектура:
до 64 МБ PSRAM
интерфейсы OPI и HPI
двухуровневый кэш (L1 + L2)
частоты до 200 МГц
аппаратное шифрование
6. Использование PSRAM в ESP-IDF
Основной компонент: esp_psram
В новых версиях ESP-IDF его нужно явно добавить в зависимости:
idf_component_register(
SRCS "main.c"
INCLUDE_DIRS "."
REQUIRES esp_psram
)После этого появляется меню:
Component config → ESP PSRAM7. Ключевые параметры menuconfig
7.1 CONFIG_SPIRAM_BOOT_INIT
Автоматическая инициализация при старте.
Рекомендуется включать.
7.2 CONFIG_SPIRAM_IGNORE_NOTFOUND
Позволяет загружаться без PSRAM.
Полезно для универсальных прошивок.
7.3 CONFIG_SPIRAM_MEMTEST
Тест памяти при старте.
≈ 1 секунда на 4 МБ.
7.4 CONFIG_SPIRAM_USE
Определяет стратегию интеграции:
1) MEMMAP
Просто отображение в адресное пространство.
Вы сами управляете памятью.
2) CAPS_ALLOC
Использование через:
heap_caps_malloc(size, MALLOC_CAP_SPIRAM);Наиболее управляемый способ.
3) MALLOC (по умолчанию)
PSRAM объединяется с общей кучей.
malloc() автоматически выбирает регион.
7.5 CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL
Порог (по умолчанию 16 КБ):
меньше → внутренняя RAM
больше → PSRAM
7.6 CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL
Резервирует внутреннюю память под:
DMA
стеки задач
критические участки
Очень важная опция для стабильности.
7.7 Перенос кода и данных
CONFIG_SPIRAM_FETCH_INSTRUCTIONS
CONFIG_SPIRAM_RODATA
CONFIG_SPIRAM_XIP_FROM_PSRAM
Позволяют:
выполнять код из PSRAM
разгрузить Flash
ускорить систему (в Octal-режиме)
8. API esp_psram
Функции:
esp_psram_init();
esp_psram_is_initialized();
esp_psram_get_size();Практически используется только:
esp_psram_get_size();9. Выделение памяти
9.1 Автоматический режим
void *ptr = malloc(size);Работает при CONFIG_SPIRAM_USE_MALLOC.
9.2 Явное выделение в PSRAM
void *ptr = heap_caps_malloc(size, MALLOC_CAP_SPIRAM);Освобождение — обычный free().
9.3 Когда использовать PSRAM
Подходит для:
больших JSON
framebuffer
аудиобуферов
кешей
временных массивов
Не подходит для:
DMA
ISR
стека задач
структур с высокой частотой доступа
10. Практическая стратегия
Оптимальный подход для production:
CONFIG_SPIRAM_USE_CAPS_ALLOC
CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL
WiFi/LWIP → в PSRAM
Стек, DMA → внутренняя RAM
Это даёт предсказуемую производительность.
11. Итог
PSRAM — это:
дешёвый способ расширить RAM
возможность работать с графикой и ML
разгрузка внутренней памяти
Но:
– всегда медленнее внутренней SRAM
– требует грамотной конфигурации
– может вызывать проблемы когерентности
Для серьёзных проектов рекомендуется:
ESP-IDF
ручное управление аллокацией
контроль DMA-буферов
резерв внутренней памяти
Create an account or sign in to leave a review
There are no reviews to display.