ESP8266:Прошивки/Arduino/Работа с файловой системой в аддоне ESP8266 для IDE Arduino

Материал из Онлайн справочника
Перейти к навигацииПерейти к поиску
Версия для печати больше не поддерживается и может содержать ошибки обработки. Обновите закладки браузера и используйте вместо этого функцию печати браузера по умолчанию.

Перевод: Максим Кузьмин
Проверка/Оформление/Редактирование: Мякишев Е.А.


Работа с файловой системой в аддоне ESP8266 для IDE Arduino[1]

Эта статья рассказывает, как в Arduino-аддоне ESP8266 осуществляется работа c файловой системой.

Разбивка flash-памяти

Хотя файловая система, как и программа, хранится во flash-памяти чипа, запись нового скетча не затрагивает содержимое файловой системы. Благодаря этому в файловой системе можно хранить, к примеру, данные скетча, конфигурационные файлы и содержимое веб-сервера.

Схема ниже показывает, какую разбивку flash-памяти использует IDE Arduino:

|--------------|-------|---------------|--|--|--|--|--|
^              ^       ^               ^     ^
Скетч     OTA-апдейт  Файл. система  EEPROM  Конфиг для WiFi (SDK)

Размер файловой системы зависит от flash-памяти на плате, выбранной в IDE Arduino:

Плата Размер flash-памяти Размер файловой системы
Generic module 512 Кб 64 Кб, 128 Кб
Generic module 1 Мб 64 Кб, 128 Кб, 256 Кб, 512 Кб
Generic module 2 Мб 1 Мб
Generic module 4 Мб 3 Мб
Adafruit HUZZAH 4 Мб 1 Мб, 3 Мб
ESPresso Lite 1.0 4 Мб 1 Мб, 3 Мб
ESPressp Lite 2.0 4 Мб 1 Мб, 3 Мб
NodeMCU 0.9 4 Мб 1 Мб, 3 Мб
NodeMCU 1.0 4 Мб 1 Мб, 3 Мб
Olimex MOD-WIFI-ESP8266(-DEV) 2 Мб 1 Мб
SparkFun Thing 512 Кб 64 Кб
SweetTea ESP-210 4 Мб 1 Мб, 3 Мб
WeMos D1 & D1 mini 4 Мб 1 Мб, 3 Мб
ESPDuino 4 Мб 1 Мб, 3 Мб
Примечание

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

#include "FS.h"

Ограничения файловой системы

Файловая система для ESP8266 должна учитывать ограничения чипа, среди которых, к примеру, ограниченная RAM. В результате выбор пал на SPIFFS, т.к. она была разработана для маленьких систем, но ценой упрощений и ограничений.

Во-первых, SPIFFS не поддерживает папки. Она просто хранит список файлов. В отличие от традиционных файловых систем, в файловых именах SPIFFS можно указывать слэши («/»), поэтому функции, которые работают с списками папок – например, openDir("/website") – просто фильтруют файловые имена в поисках тех, что начинаются с запрошенного префикса. Например, с того же "/website".

Во-вторых, максимальный размер для файлового имени – 32 символа. Более того, символ «\0» отведен под завершение строки, поэтому в итоге у нас остается даже не 32, а 31 символ.

Таким образом, файловые имена SPIFFS должны быть короткими, из чего вытекает другое ограничение – файловые имена не должны быть слишком многоуровневыми. Потому что, опять же, полный размер пути к каждому файлу (включая папки, символы «/», само название, точку и расширение) не должен превышать 31 символ. К примеру, файловое имя /website/images/bird_thumbnail.jpg состоит из 34 символов, и это может повлечь проблемы, к примеру, при использовании функции exists() или если имя другого файла будет иметь тот же 31 символ.

Внимание!

Пропустить это ограничение очень просто. Если его проигнорировать, проблема может пройти незамеченной, потому что никаких сообщений об ошибках показано не будет – ни во время компиляции, ни во время работы скетча.

Боле подробно о реализации SPIFFS на ESP8266 читайте здесь.

Загрузка файлов в файловую систему

ESP8266FS – это инструмент, интегрируемый в IDE Arduino. Он добавляет новый пункт в меню Инструменты (Tools), который предназначен для загрузки данных скетча в файловую систему ESP8266, находящуюся на flash-памяти.

  1. Загрузите инструмент, кликнув по этой ссылке
  2. В папке скетчей IDE Arduino создайте папку «tools», если она еще не создана
  3. Распакуйте скачанный инструмент в папку «tools». В результате путь будет выглядеть примерно так: <дом_папка>/Arduino/tools/ESP8266FS/tool/esp8266fs.jar
  4. Перезапустите IDE Arduino
  5. Откройте скетч (или создайте новый и сохраните его)
  6. Откройте папку этого скетча. Для этого кликните по Скетч > Показать папку скетча (Sketch > Show Sketch Folder)
  7. Создайте папку «data» и прочие файлы, которые хотите сохранить в файловую систему
  8. Кликните в IDE Arduino по Инструменты > ESP8266 Sketch Data Upload (Tools > ESP8266 Sketch Data Upload). Это должно начать загрузку файлов в файловую систему ESP8266. Когда загрузка будет завершена, статусная панель IDE Arduino покажет сообщение «SPIFFS Image Uploaded», что значит «образ SPIFFS загружен».

Объект файловой системы (SPIFFS)

Здесь будет рассказано о функциях, используемых с объектом SPIFFS.

  • Функция SPIFFS.begin() устанавливает файловую систему SPIFFS. Ее нужно вызывать самой первой, т.е. до вызова всех остальных функций для работы с файловой системой. Возвращает true, если файловая система успешно установлена, и false – если нет.
  • Функция SPIFFS.end() демонтирует файловую систему SPIFFS. Используйте эту функцию перед обновлением SPIFFS методом OTA.
  • Функция SPIFFS.format() форматирует файловую систему. Ее можно вызывать и до, и после SPIFFS.begin().
  • Функция SPIFFS.open(path, mode) открывает файл. Аргумент path – это абсолютный путь, который начинается со слэша и выглядит примерно так: /dir/filename.txt. Аргумент mode – это строка, указывающая режим доступа. Допустимые значения для аргумента mode: r, w, a, r+, w+ и a+. Принципы работы этих режимов – такие же, как у C-функции fopen().
    • Режим «r». Открывает текстовый файл для чтения. Указатель ставится в начало файла.
    • Режим «r+». Открывает текстовый файл для чтения и записи. Указатель ставится в начало файла.
    • Режим «w». Усекает файл до нулевого размера или создает текстовый файл для записи. Указатель ставится в начало файла.
    • Режим «w+». Открывает текстовый файл для записи или чтения. Если файла не существует, он создается. В противном случае он усекается. Указатель ставится в начало файла.
    • Режим «a». Открывает файл для дополнения (записи в конец файла). Если файла не существует, он создается. Указатель ставится в конец файла.
    • Режим «a+». Открывает файл для чтения и дополнения (записи в конец файла). Если файл не существует, он создается. При чтении начальная позиция файла – в начале, но дополнение всегда выполняется в конце файла.

Возвращает объект File. Чтобы проверить, успешно ли был открыт файл, воспользуйтесь оператором if:

File f = SPIFFS.open("/f.txt", "w");
if (!f) {
    Serial.println("file open failed");  //  "открыть файл не удалось"
}
  • Функция SPIFFS.exists(path) возвращает true, если указанный путь (аргумент path) существует, а если не существует, возвращает false.
  • Функция SPIFFS.openDir(path) открывает директорию, путь к которой указан в аргументе path. Возвращает объект Dir.
  • Функция SPIFFS.remove(path) удаляет файл, путь к которому указан в аргументе path. Если файл удален успешно, возвращает true.
  • Функция SPIFFS.rename(pathFrom, pathTo) переименовывает файл с pathFrom на pathTo. Пути, указанные в этих аргументах, должны быть абсолютными. Если файл успешно переименован, возвращает true.
  • Функция SPIFFS.info() заполняет структуру FSInfo информацией о файловой системе. Если задача выполнена успешно, возвращает true, а если нет – false. Пример использования:
FSInfo fs_info;
SPIFFS.info(fs_info);


Структура FSInfo

struct FSInfo {
    size_t totalBytes;
    size_t usedBytes;
    size_t blockSize;
    size_t pageSize;
    size_t maxOpenFiles;
    size_t maxPathLength;
};

Это структура, которую можно заполнить данными при помощи функции SPIFFS.info().

  • totalBytes – это общий размер полезных данных в файловой системе
  • usedBytes – количество байт, используемых файлами
  • blockSize – размер блока SPIFFS
  • pageSize – это размер логической страницы SPIFFS
  • maxOpenLength – это максимальное количество файлов, которые можно открыть одновременно
  • maxPathLength – это максимальная длина файлового имени (включая один байт для завершающего нуля)

Объект директории (Dir)

Цель объекта Dir – это перебор файлов внутри директории. У этого объекта существуют три функции – next(), fileName() и openFile(mode). Фрагмент кода ниже показывает пример использования всех трех функций:

Dir dir = SPIFFS.openDir("/data");
while (dir.next()) {
    Serial.print(dir.fileName());
    File f = dir.openFile("r");
    Serial.println(f.size());
}

Если в директории есть файлы, которые можно перебрать, функция dir.next() вернет true. Ее нужно вызывать первой, до вызова функций fileName() и openFile().

У функции openFile() есть аргумент mode, который работает по тому же принципу, что и аргумент mode в функции SPIFFS.open().

Объект File

Функции SPIFFS.open() и dir.openFile() возвращают объект File. Этот объект поддерживает все функции класса Stream, поэтому с ним можно использовать функции readBytes(), findUntil(), parseInt(), println() и т.д.

Но у объекта File есть и несколько собственных функций.

Функция file.seek(offset, mode) ведет себя аналогично C-функции fseek(). Аргумент mode указывает, в какое место файла нужно поставить курсор:

  • Если в аргументе mode будет стоять значение SeekSet, курсор будет поставлен на offset байтов от начала файла
  • Если в аргументе mode будет стоять значение SeekCur, текущая позиция курсора будет передвинута на offset байтов
  • Если в аргументе mode будет стоять значение SeekEnd, курсор будет поставлен на offset байтов от конца файла

Если курсор установлен успешно, возвращает true.

Функция file.position() возвращает текущую позицию внутри файла (в байтах).

Функция file.size() возвращает размер файла (в байтах).

Функция file.name() возвращает название файла в виде const char*. Чтобы сохранить, конвертируйте его в String:

String name = file.name();

Функция file.close() закрывает файл. После вызова этой функции никаких других операций с объектом File выполняться не должно.

См.также

Внешние ссылки