Гайд · Память · Хранение
Flash, SRAM, NVS — где реально живут твои данные
Три вопроса ставят в тупик каждого новичка на ESP: почему настройки слетают после перезагрузки? почему сбрасываются переменные? почему кончается RAM? Все три сводятся к одному — надо знать, какая память что хранит. Вот карта и как правильно сохранять конфиг.
Типы памяти
- Flash — энергонезависимая. Хранит программу и данные, переживающие отключение питания. Большая (МБ), но медленная на запись и ограничена ~100k циклов стирания на сектор.
- SRAM — быстрая волатильная рабочая память под переменные, кучу и стек. ~320 КБ на ESP32, ~80 КБ на ESP8266. Стирается при каждой перезагрузке — вот почему переменные сбрасываются.
- RTC RAM — крошечный кусочек, переживающий глубокий
сон (через
RTC_DATA_ATTR). При полном отключении питания всё равно теряется. - EEPROM — старый ардуиновский способ хранить мелочь. На ESP настоящего EEPROM нет;
EEPROM.hпросто эмулирует его во flash. - NVS (Preferences) — современный правильный способ хранить конфиг «ключ-значение» во flash на ESP32/ESP8266: именованный, типизированный, с выравниванием износа.
Почему настройки слетают
Переменные живут в SRAM, а она волатильна — выключил питание, и всё пропало. Чтобы сохранить пароль Wi-Fi, калибровку или пользовательскую настройку между перезагрузками, надо писать в энергонезависимое хранилище: NVS или flash.
Сохраняем конфиг правильно — Preferences (NVS)
Забудь про EEPROM.h на ESP. Используй библиотеку Preferences — она пишет
именованные типизированные значения в NVS и сама следит за износом:
#include <Preferences.h>
Preferences prefs;
void saveConfig(const char* ssid, int interval) {
prefs.begin("cfg", false); // namespace "cfg", чтение/запись
prefs.putString("ssid", ssid);
prefs.putInt("interval", interval);
prefs.end();
}
void loadConfig() {
prefs.begin("cfg", true); // только чтение
String ssid = prefs.getString("ssid", ""); // значение по умолчанию, если пусто
int every = prefs.getInt("interval", 60);
prefs.end();
} Вызови loadConfig() в setup() — и настройки на месте после каждой
перезагрузки, с разумными дефолтами в первый раз. Ровно так библиотеки хранят учётки Wi-Fi.
EEPROM против Preferences
На классическом Arduino EEPROM — настоящее железо. На ESP его нет: EEPROM.h эмулирует блок
во flash, с адресацией по байтам и лёгкой порчей данных. Preferences (NVS) даёт
именованные ключи, типы и выравнивание износа вместо сырых байтовых смещений. Для всего нового — только
он.
Кончается RAM
SRAM маленькая, её легко исчерпать или фрагментировать:
- Держи константы во flash — оборачивай строковые литералы в
F("...")(илиPROGMEM), чтобы они не ели SRAM. - Избегай возни со String — постоянная конкатенация
String +фрагментирует кучу; лучше фиксированныеchar-буферы или резервируй ёмкость. - Следи за кучей — печатай
ESP.getFreeHeap(); стабильное падение — течь. - Большие буферы? ESP32-S3 с PSRAM даёт мегабайты под кадры камеры и дисплеи — см. гид по чипам.
Что где хранить — шпаргалка
- Код программы → flash
- Переменные, куча, стек → SRAM (волатильно)
- Конфиг и учётки → NVS / Preferences
- Переживает глубокий сон → RTC RAM
- Большие константы / ассеты → flash (PROGMEM) или PSRAM
Как только понимаешь, какая память волатильна, а какая нет, загадки исчезают: настройки сохраняются, переменные ведут себя предсказуемо, а RAM перестаёт кончаться.
Нужно, чтобы значение пережило глубокий сон, а не только ребут? Это RTC-память.