ESP-IDF: файловая система SPIFFS Печать
Добавил(а) microsin   

SPIFFS это файловая система, предназначенная для микросхем SPI NOR flash на target-ах ESP32. Библиотека поддерживает wear levelling (равномерный износ ресурса секторов flash), проверки целостности файловой системы, и другие функции.

Замечания:

• В настоящий момент SPIFFS не поддерживает директории, используя плоскую структуру доступа к файлам. Если SPIFFS смонтирована на /spiffs, то создание файла с путем /spiffs/tmp/myfile.txt создаст файл /tmp/myfile.txt в SPIFFS вместо того, чтобы файл myfile.txt размещался в директории /spiffs/tmp.
• Это не стек реального времени выполнения, т. е. длительность операций не прогнозируемая. Одна операция записи может по времени происходить намного дольше другой.
• В настоящее время библиотека не обнаруживает и не обрабатывает проблемы сбойных блоков (bad block).
• SPIFFS может надежно утилизировать около 75% назначенного пространства раздела.
• Когда файловая система выходит за доступное пространство, сборщик мусора (garbage collector, GC) пытается найти свободное место, несколько раз сканируя файловую систему, что может занять несколько секунд на один вызов функции записи, в зависимости от требуемого пространства. Причина такого поведения в дизайне SPIFFS, и о проблеме сообщалось несколько раз в репозитории espressif [2], а также в официальном репозитории несколько [3]. Эту проблему можно частично обойти конфигурированием SPIFFS.
• Удаление файла не всегда удаляет весь файл, что оставляет не используемые секции во всей файловой системе.
• Когда ESP32 сталкивается с пропаданием питания во время операцией над файловой системой, это может повредить SPIFFS. Однако файловую систему все еще можно восстановить вызовом функции esp_spiffs_check. Более подробно про это написано в официальном SPIFFS FAQ [4].

[Инструментарий]

spiffsgen.py. Это скрипт на Python, предназначенный для wtite-only реализации SPIFFS. Скрипт spiffsgen.py используется для создания образов файловой системы из содержимого папки хоста. Для использования spiffsgen.py откройте консоль и запустите команду:

python spiffsgen.py < image_size > < base_dir > < output_file >

Требуемые аргументы скрипта следующие.

• image_size: размер раздела SPI flash, куда будет прошит созданный образ SPIFFS.
• base_dir: директория, для которой нужно создать образ SPIFFS.
• output_file: выходной файл образа SPIFFS.

Существует также множество других аргументов, управляющих генерацией образа. Документация по этим аргументам может быть получена опцией --help:

python spiffsgen.py --help

Эти опциональные аргументы соответствуют возможной конфигурации сборки SPIFFS. Для генерации правильного образа убедитесь, что используете те же аргументы/конфигурацию, что и сборка SPIFFS. В качестве руководства к действию вывод --help показывает конфигурацию сборки SPIFFS, которой соответствует аргумент. В случаях, когда эти аргументы не указаны, в выводе --help показаны используемые значения по умолчанию.

Когда образ создан, он может быть прошит с помощью esptool.py или parttool.py.

Кроме вызова spiffsgen.py вручную из командной строки или скрипта, есть возможность вызвать spiffsgen.py из системы сборки с помощью функции spiffs_create_partition_image:

spiffs_create_partition_image(< partition > < base_dir > [FLASH_IN_PROJECT] [DEPENDS dep dep dep...])

Это удобнее, поскольку конфигурация сборки передается в утилиту, что гарантирует соответствие генерируемого образа для сборки. Например, если image_size требуется для автономного вызова, то требуется только имя раздела, когда используется spiffs_create_partition_image – размер образа автоматически извлекается из таблицы разделов проекта.

Функция spiffs_create_partition_image должна вызываться из одного из файлов CMakeLists.txt компонента.

При необходимости пользователи могут выбрать автоматическую прошивку образа вместе с бинарниками приложения, таблицами разделов и т. д. в команде idf.py flash путем указания FLASH_IN_PROJECT. Например:

spiffs_create_partition_image(my_spiffs_partition my_folder FLASH_IN_PROJECT)

Если FLASH_IN_PROJECT/SPIFFS_IMAGE_FLASH_IN_PROJECT не указаны, то образ будет создан, но его надо будет прошить во flash вручную с помощью esptool.py, parttool.py, или используя пользовательский системный target.

Существуют случаи, когда содержимое самой базовой директории base_dir генерируется во время сборки. Пользователи могут использовать DEPENDS/SPIFFS_IMAGE_DEPENDS, чтобы указать target-ы, которые должны быть выполнены перед генерацией образа:

add_custom_target(dep COMMAND ...)
spiffs_create_partition_image(my_spiffs_partition my_folder DEPENDS dep)

Для примера см. examples\storage\spiffsgen.

mkspiffs. Это другая утилита для создания образов раздела SPIFFS [5]. Подобно spiffsgen.py, утилита mkspiffs может использоваться для создания образа из указанной папки, и последующей прошивки в SPI flash с помощью esptool.py.

Для этого необходимы следующие параметры:

• Block Size: 4096 (стандартный размер блока в байтах для SPI Flash).
• Page Size: 256 (стандартный размер страницы в байтах для SPI Flash).
• Image Size: размер раздела в байтах (может быть получен из таблицы разделов []).
• Partition Offset: начальный адрес раздела в памяти SPI flash (может быть получен из таблицы разделов).

Для упаковки папки в 1-мегабайтный раздел, запустите:

mkspiffs -c [src_folder] -b 4096 -p 256 -s 0x100000 spiffs.bin

Для прошивки образа в память модуля ESP32 со смещением 0x110000:

esptool.py --chip esp32 --port [port] --baud [baud] write_flash -z 0x110000 spiffs.bin

Две представленные утилиты обладают похожим функционалом. Однако есть некоторые причины, по которым может быть предпочтительнее выбрать одну из них, в зависимости от ситуации.

Используйте spiffsgen.py в следующих случаях:

1. Если хотите просто сгенерировать образ SPIFFS во время сборки проекта. Утилита spiffsgen.py делает это очень удобным способом, предоставляя функции/команды из самой системы сборки.
2. Если у хоста нет компилятора C/C++, потому что spiffsgen.py не требует компиляции.

Используйте mkspiffs в следующих случаях:

1. Если хотите иметь возможность распаковать образы SPIFFS в дополнение к генерации образа. В настоящий момент распаковку образов утилита spiffsgen.py делать не умеет.
2. Если у Вас рабочее окружение, в котором недоступен интерпретатор Python, однако на хосте доступен компилятор. Также предварительно скомпилированный код mkspiffs может выполнить задание. Однако нет интеграции mkspiffs с системой сборки, и пользователю нужно вручную сделать соответствующую работу: сначала скомпилировать mkspiffs (если бинарника утилиты mkspiffs пока нет), создать сборку rules/targets для выходных файлов, передать правильные параметры утилите, и т. д.

Пример приложения, которое использует SPIFFS, предоставлен в директории examples\storage\spiffs среди других примеров среды разработки ESP-IDF. этот пример инициализирует и монтирует раздел SPIFFS, затем записывает и читает данные с него вызовами библиотечных API-функций POSIX и C. См. файл README.md в директории примера для дополнительной информации.

[Справочник по API верхнего уровня]

Заголовочный файл components/spiffs/include/esp_spiffs.h.

Функция Описание
esp_vfs_spiffs_register Регистрирует и монтирует SPIFFS для VFS [7] с указанным префиксом пути.
esp_vfs_spiffs_unregister Дерегистрирует и размонтирует SPIFFS.
esp_spiffs_mounted Проверка - смонтирована ли SPIFFS.
esp_spiffs_format Форматирует раздел SPIFFS.
esp_spiffs_check Проверяет целостность SPIFFS.
esp_spiffs_gc Выполняет сборку мусора в разделе SPIFFS.

Замечание по поводу функции esp_spiffs_gc. Вызовите эту функцию, чтобы запустить сборщик мусора (Garbage Collector, GC), и убедитесь, что в разделе доступен хотя бы заданный объем пространства. Эта функция вернет ошибку ESP_ERR_NOT_FINISHED, если невозможно получить запрошенный объем (т. е. недостаточно свободных или удаленных страниц в файловой системе). Эта функция также вернет ошибку, если не сможет получить запрошенное пространство после выполнения CONFIG_SPIFFS_GC_MAX_RUNS итераций GC. На одной итерации GC, SPIFFS сотрет один логический блок (4 килобайта). Поэтому значение CONFIG_SPIFFS_GC_MAX_RUNS должно быть установлено, по крайней мере на максимальное ожидаемое значение size_to_gc, поделенное на 4096. Например, если приложение ожидает освободить место для файла 1MB, и вызовет esp_spiffs_gc(label, 1024 * 1024), то CONFIG_SPIFFS_GC_MAX_RUNS должно быть установлено как минимум в 256. С другой стороны, увеличение CONFIG_SPIFFS_GC_MAX_RUNS увеличит максимальное время для любого запуска SPIFFS GC, или операции записи могут быть потенциально заблокированы.

Подробное описание функций и типов данных см. в документации [1].

[Ссылки]

1. ESP-IDF SPIFFS Filesystem site:docs.espressif.com.
2. Only 80-87% of a SPIFFS partition on the internal Flash Chip can be used to store data files site:github.com.
3. pellepl / spiffs issues site:github.com.
4. pellepl / SPIFFS FAQ site:github.com.
5. igrr / mkspiffs site:github.com.
6. ESP32: таблицы разделов.
7. ESP VFS: виртуальная файловая система.