• Уважаемые посетители сайта esp8266.ru!
    Мы отказались от размещения рекламы на страницах форума для большего комфорта пользователей.
    Вы можете оказать посильную поддержку администрации форума. Данные средства пойдут на оплату услуг облачных провайдеров для сайта esp8266.ru
  • Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

"Низкоуровневый" доступ к SPIFFS

702

New member
Здравствуйте.

Осваиваю работу с файловой системой SPIFFS. FreeRTOS SDK, без Ардуины.

Во всех примерах для работы с файлами используются потоковые функции. Я хочу использовать обычный бинарный ввод-вывод.
Нашел в АПИ низкоуровневые функции SPIFFS_open, SPIFFS_read итд. В качестве параметра им нужно передать указатель на структуру типа spiffs. Беглый просмотр исходников показал, что это описатель раздела, массив которых хранится в памяти библиотеки SPIFFS.
Но этот массив объявлен как static, и методов доступа к нему я не нашел. Можно конечно, пропатчить библиотеку: добавить функцию, возвращающую указатель; добавить поле в структуру esp_vfs_spiffs_conf и инициализировать его при регистрации; или вовсе убрать static, что уже совсем грубо.
Или скопировать исходник библиотеки к себе в проект и уже там резвиться.

Или можно как-нибудь еще?
 

exeland

Member
вот примеры работы - pellepl/spiffs
В примерах же напрямую с функциями работают. spiffs __fs - глобальная переменная прописанная test_spiffs.c
 

702

New member
вот примеры работы - pellepl/spiffs
Эти примеры есть прямо в составе SDK. Но тут придется смириться либо с частичным дублированием кода, либо с потерей возможности
потоковых операций. Пока решил при необходимости пользоваться патченной библиотекой, хотя это и некрасиво.
Но все равно спасибо.
 

702

New member
Продолжаю экспериментировать со SPIFFS.
Попытался создать свой образ размером 64 килобайта, содержаший единственный файл. Создавал при помощи mkspiffs.
В настройках проекта указал:

SPIFFS Filesystem Magic = 1,
Enable SPIFFS Filesystem Length Magic = 1
Size of per-file metadata field = 0

по рекомендациям автора mkspiffs.

Образ разместил по адресу 0xb0000. Образ нормально монтируется, приложение создает, читает и пишет файлы без проблем.
При этом файл, который изначально находился в образе открывается успешно, но при его чтении возникает ошибка.
В считанном и распакованном после работы приложения образе ровно наоборот:
"мой" файл в порядке, имена созданных приложением файлов правильные, но внутри файлов мусор.

Если создать образ при помощи spiffsgen.py с соответствующими настройками, ситуация один-в-один.

В чем может быть дело?
 

702

New member
Сам отвечаю на свой вопрос.

Путем изучения исходников и втыкания в них многочисленных отладочных сообщений (нормального описания этой самой SPIFFS нет),
а также побайтового сравнения образов, сгенеренных на ПК и приложением, выяснил, что SDK при сборке приложения игнорирует настройку
"Size of per-file metadata field = 0"
в конфиге, и всегда вставляет в структуру заголовка страницы поле, размером один байт. Оно не последнее в структуре. Соответственно, в образе, созданном без этого поля, значения последующих полей оказываются сдвинутыми и принимают непредсказуемые значения.

Решение: создавать образы с включенным полем metadata.

Вдруг кому пригодится.
 

Slacky

Member
Подниму тему. Решил загрузить spiffs с помощью mkspiffs. Все хорошо. Собрал mkspiffs. Подсунул при компиляции mkspiffs sdkconfig.h от проекта. Собралось все с теми же параметрами, как в sdlconfig. Но все равно не работает. Листинг показывает, что файлы есть, но прочитатать не могу - 0.

Код:
CONFIG_SPIFFS_MAX_PARTITIONS=3
CONFIG_SPIFFS_CACHE=y
CONFIG_SPIFFS_CACHE_WR=y
# CONFIG_SPIFFS_CACHE_STATS is not set
CONFIG_SPIFFS_PAGE_CHECK=y
CONFIG_SPIFFS_GC_MAX_RUNS=10
# CONFIG_SPIFFS_GC_STATS is not set
CONFIG_SPIFFS_PAGE_SIZE=256
CONFIG_SPIFFS_OBJ_NAME_LEN=32
CONFIG_SPIFFS_USE_MAGIC=y
CONFIG_SPIFFS_USE_MAGIC_LENGTH=y
CONFIG_SPIFFS_META_LENGTH=4
CONFIG_SPIFFS_USE_MTIME=y
Код:
$ ./mkspiffs --version
mkspiffs ver. 0.2.3-7-gf248296
Build configuration name: generic
SPIFFS ver. 0.3.7-5-gf5e26c4
Extra build flags: (none)
SPIFFS configuration:
  SPIFFS_OBJ_NAME_LEN: 32
  SPIFFS_OBJ_META_LEN: 4
  SPIFFS_USE_MAGIC: 1
  SPIFFS_USE_MAGIC_LENGTH: 1
  SPIFFS_ALIGNED_OBJECT_INDEX_TABLES: 0
C:
static esp_err_t read_file(const char *filename) {

    char buff[1024];
    size_t size;

    sprintf(buff, "%s%s%s", DIR_PATH, DELIM, filename);
    printf("%s\n", buff);

    FILE *f = fopen(buff, "rb");
    if (f == NULL) {
        ESP_LOGE(TAG, "Cannot open file %s", buff);
        return ESP_FAIL;
    }

    do {
        size = fread(buff, 1, sizeof(buff), f);
        printf("size - %d\n", size);
        if (size > 0) {
            printf(buff);
        }
    } while (size == sizeof(buff));

    fclose(f);

    return ESP_OK;
}
Ну и вывод

Код:
I (290) main.c: Initializing SPIFFS
Directory: /spiffs/html

/spiffs/html/config.html
size - 0
/spiffs/html/favicon.ico
size - 0
/spiffs/html/index.html
size - 0
/spiffs/html/log.html
size - 0
/spiffs/html/ok.html
size - 0
/spiffs/html/scripts.js
size - 0
/spiffs/html/settings.html
size - 0
/spiffs/html/style.css
size - 0
/spiffs/html/upload.html
size - 0

Used 0  bytes
Free 388548     bytes
Есть идеи куда копать?
 

Slacky

Member
Разобрался, точнее скорей потыкал, чем понял.

При
CONFIG_SPIFFS_META_LENGTH=1

все прекрано работает.
 

Slacky

Member
Вроде логично.
Вроде да, но не вполне. Если прочесть фразу целиком, то смысл все-таки немного другой. Я это понял так - при 0 все равно 1.

Я не стал разбираться по коду, когда именно меняется настройка из sdkconfig на 1. Но. В esp32 компонент spiffs один в один как и для esp8266. И в esp32 все работает из коробки, а sdkconfig в части spiffs у них одинаковый.
 
Сверху Снизу