Перейти к содержанию

NVS — энергонезависимое хранилище ESP32

Чтобы сохранить настройки ESP32 между перезагрузками — пароль Wi-Fi, калибровку датчика, счётчик запусков, — не нужно разбираться с секторами флеш-памяти. Для этого в ESP-IDF есть NVS: хранилище пар «ключ — значение», устойчивое к пропаданию питания.

Обновлено Редакция GAW

NVS (non-volatile storage) — библиотека ESP-IDF для хранения пар «ключ — значение» во флеш-памяти ESP32. Она работает с разделами таблицы разделов с типом data и подтипом nvs и прячет от программы секторы, стирание и износ: программа открывает пространство имён, записывает и читает значения по ключам. Ключ — строка ASCII до 15 символов, значение — целое от 8 до 64 бит, float или double, строка или двоичный блок (ESP-IDF, Non-Volatile Storage Library).

Как устроено

  • Пространства имён. Каждая пара принадлежит пространству имён (до 15 символов, не больше 254 на раздел), чтобы ключи разных компонентов не пересекались.
  • Страницы и записи. Страница — это сектор флеш-памяти 4096 байт, данные пишутся записями по 32 байта; строки и блоки занимают несколько записей подряд.
  • Журнальная запись. Новые значения дописываются в свободное место, старые лишь помечаются удалёнными. Так уменьшается число стираний, и NVS по устройству выравнивает износ.
  • Пропадание питания. Библиотека восстанавливается после отключения в любой момент; теряется только пара, которая записывалась в этот момент.

Работа с API

Раздел инициализируют функцией nvs_flash_init(), затем открывают пространство имён nvs_open() в режиме NVS_READONLY, NVS_READWRITE или NVS_READWRITE_PURGE и пишут функциями nvs_set_*. Запись гарантированно попадает во флеш-память после nvs_commit(). При чтении тип проверяется: если он не совпадает с сохранённым, функция вернёт ошибку. Если раздел обрезан, например после изменения таблицы разделов, его содержимое нужно стереть.

NVS и EEPROM

Для ESP32 NVS выполняет ту же роль, что встроенная EEPROM у AVR, — хранит небольшие настройки, но поверх флеш-памяти с секторами по 4 КБ (наш вывод из назначения библиотеки). Те же разделы ESP-IDF использует для калибровки радио и данных Wi-Fi. Без шифрования данные NVS читаются с флеш-микросхемы напрямую; при включённом шифровании NVS ключи хранятся в разделе nvs_keys, который шифрует шифрование флеш-памяти. Обзор чипов — в разделе ESP32.

Частые вопросы

Почему значение не сохранилось после перезагрузки?

Частая причина — не вызван nvs_commit(). По документации ESP-IDF функции nvs_set_* не обязаны сразу обновить флеш-память: фактическая запись может произойти только после nvs_commit. Ещё одна причина — свободного места нет: для новой пары нужны свободные записи, а для строки — непрерывный ряд записей в одной странице.

Сколько данных помещается в NVS?

Зависит от раздела: в стандартной таблице ESP-IDF он 0x6000 байт (24 КБ), рекомендуемый минимум — 0x3000. Одна строка — до 4000 байт, двоичный блок — до 508 000 байт или 97,6 % раздела минус 4000 байт. Espressif советует хранить в NVS много мелких значений, а большие массивы — в файловой системе FAT с выравниванием износа.

Защищены ли данные NVS?

По умолчанию нет: ESP-IDF прямо пишет, что без шифрования NVS любой, кто имеет физический доступ к флеш-микросхеме, может читать и менять пары. Шифрование NVS вместе с шифрованием флеш-памяти закрывает чтение и подделку, но не защищает от стирания. Удалённые значения по умолчанию лишь помечаются; для физического стирания есть режим NVS_READWRITE_PURGE.

Источники

  1. Espressif. ESP-IDF Programming Guide v6.1: Non-Volatile Storage Library (ESP32) — NVS хранит пары «ключ — значение» во флеш-памяти в разделах с типом data и подтипом nvs; nvs_flash_init() — раздел с меткой nvs; ключи ASCII до 15 символов; значения: целые 8–64 бит, строки, двоичные блоки (blob), float и double; строка до 4000 байт, blob до 508 000 байт или 97,6 % раздела минус 4000 байт; пространства имён до 15 символов, не больше 254 на раздел; режимы NVS_READONLY, NVS_READWRITE, NVS_READWRITE_PURGE; без шифрования NVS данные читаются с флеш-микросхемы; при пропадании питания теряется только записываемая пара; удалённые данные лишь помечаются; страница — сектор 4096 байт, запись по 32 байта; встроенное выравнивание износа; nvs_set_* — фактическая запись может произойти только после nvs_commit; обрезанный раздел NVS нужно стереть
  2. Espressif. ESP-IDF Programming Guide v6.1: Partition Tables (ESP32) — подтип nvs (2) — для NVS API, хранит калибровку PHY и данные Wi-Fi при WIFI_STORAGE_FLASH; рекомендуется раздел NVS не меньше 0x3000 байт, по умолчанию 0x6000; для заводских настроек — отдельный раздел только для чтения от 0x1000 байт

Нашли ошибку?