Помимо файловой системы SPIFFS в контроллере ESP32 для энергонезависимого хранения данных используется также энергонезависимое хранилище данных NVS.
Энергонезависимое хранилища данных (Non-volatile storage, NVS) работает на уровне комплекта IDF и разработано оно для хранения пар ключ-значение в памяти FLASH.
Данный способ хранения порой упрощает работу с хранением структурированных данных, так как хранить их в файлах не совсем рентабельно. Так как файл надо полностью открыть, закрыть, перезаписать весь при незначительном изменении и т.д.
Комплект IDF предоставляет очень немалый функционал по работе с NVS, только полностью мы с ним со всем не будем в рамках данного занятия знакомиться, а познакомимся мы лишь с некоторой частью данного функционала. Это позволит нам не нагромождать теорию в мозгах и легче усвоить материал. То есть мы будем знакомиться лишь с той частью, которая, как я считаю нам пригодится в недалёком будущем, а если нам потребуется знать что-то ещё, мы всегда успеем это сделать.
Схема наша будет состоять из платы с контроллером ESP32, подключенной к порту USB компьютера
А проект мы возьмём из давнего урока 4, в котором мы работали с кнопкой, с именем BUTTON01 и на его основе создадим проект с именем NVS01.
Откроем наш проект в ESPRESSIF IDE и из файла Kconfig.projbuild удалим пункт меню по работе с ножкой, к которой была подключена кнопка (BUTTON_GPIO). Также в данном файле ножку порта по умолчанию для светодиода выберем вторую
default 48 if IDF_TARGET_ESP32S3
default 2
В функции app_main файла main.c оставим только вот эти строки
Не забываем также в конфигураторе выбрать 4 мегабайта объёма памяти FLASH
Попробуем собрать наш проект. Если всё нормально собирается, то ещё создадим заголовочный файл main.h, в который соберём все подключенные заголовочные файлы из main.c, а заодно и подключим заголовочные файлы для работы с хранилищем NVS
Вернёмся в main.c и удалим подключение всех заголовочных файлов, а подключим только один
В принципе, мы немного уже затрагивали тему хранилища NVS. По крайней мере, в проектах с использованием сети WiFi мы её инициализировали. Добавим такой же код инициализации в функции app_main и сейчас
Попробуем собрать проект и прошить его.
Запустим терминал и посмотрим, где у нас находится раздел хранилища nvs и каков его объём
С помощью esptool для чистоты эксперимента мы полностью очистим данный участок памяти
Вернёмся в наш проект в функцию app_main файла main.c и попробуем вывести терминал об уже существующих записях в хранилище
Краткое описание используемых функций в данном блоке кода:
nvs_entry_find возвращает итератор, который используется в последующих вызовах и который позволяет пролистать пары ключ-значение, сохраненные в NVS, основываясь на имени раздела, namespace, и типе данных;
nvs_entry_info возвращает информацию для каждой пары ключ-значение;
nvs_entry_next возвращает итератор для следующей пары ключ-значение.
Также следует отметить, что хранилище nvs позволяет работать с очень широким списком типов данных, а именно int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t, строками, а также данными переменной длины (blob).
Соберём код, прошьём контроллер и посмотрим результат работы кода в терминале
Наш код нам ничего не вернул.
Это результат того, что мы очистили раздел. Если бы перед этим был бы прошит проект прошлого урока, то у нас бы были данные, так как мы работали с WiFi.
Поэтому давайте попробуем что-нибудь записать в хранилище.
Для этого мы сначала должны объявить хендл и открыть хранилище, передав ему пространство имён, способ открытия и адрес хендла. Затем мы пока закроем наше хранилище при удачном его открытии
А дальнейший код мы уже будем, соответственно, писать перед закрытием хранилища nvs.
Попробуем собрать код и прошить контроллер.
В терминале мы видим, что хранилище удачно открылось
Попробуем что-нибудь записать в наше хранилище. Для этого сначала объявим инициализируем несколько переменных различных целочисленных типов
Затем попробуем записать данные значения в хранилище под различными именами ключей
Соберём код, прошьём контроллер и посмотрим результат
Если мы перезагрузим контроллер после этого, то предыдущий код по перебору записей нам также даст результаты
Мы можем не бояться, перезагружая контроллер, того, что у нас будет повторяться процесс записи и тем самым вызовет задвоение данных. Здесь ситуация такая. Если данные пишутся под уже существующим именем ключа, то они не создают новую пару ключ-значение в том случае, если не изменился тип данных, они просто модифицируются, если есть изменение значения.
Мы также видим в терминале только типы данных, сами данные мы не видим.
Давайте запишем ещё и строки
По окончанию записи мы вызываем функцию nvs_commit для применения изменений.
А чтобы видеть значения данных, для этого мы напишем код следующий.
Для начала в целях чистоты эксперимента мы объявим новые переменные, так как в существующих у нас уже есть значения
Затем прочитаем пока целочисленные ключи и отобразим значения в терминале
Далее прочитаем ключи строкового (символьного) типа. Здесь всё несколько заморочено
Соберём код, прошьём контроллер и посмотрим результат в терминале
Всё отлично прочиталось!
Итак, на данном уроке мы познакомились с энергонезависимым хранилищем NVS, а также поупражнялись с записью в данное хранилище и чтением из него различных типов данных.
Всем спасибо за внимание!
Оригинал статьи находится здесь.
Недорогие отладочные платы ESP32 можно купить здесь
Недорогие отладочные платы ESP32/ESP32-C3/ESP32-S3 можно купить здесь
Логический анализатор 16 каналов можно приобрести здесь
Многофункциональный переходник CJMCU FT232H USB к JTAG UART FIFO SPI I2C можно купить здесь
Видео в Rutube
Видео в Дзен
Видео в Youtube