• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

SPIFFS теряет файлы

rkit

New member
Простая система логов. Один файл постоянно открыт, в него периодически добавляются строки. Когда вырастает до некоторого размера, добавляется новый файл. Периодически старые файлы подчищаются.
Проблема в том, что когда в файл записывается новая строчка, он может исчезнуть из листинга. А потом, при случайной операции записи - появляется опять. Даже после перезагрузки проходит несколько записей в другой файл, и этот появляется. И больше не исчезает.
Кто-нибудь сталкивался с таким?
На износ флеша грешить не хочется, потому что плата новая, да и проблема проявляется строго в одном месте.

Код:
Dir dir = SPIFFS.openDir("/stats/");
while (dir.next()) {
  response->printf("<p><a href='/fs%s'>%s</a></p>", dir.fileName().c_str(), dir.fileName().c_str());
}
 

rkit

New member
На наличие файла в списке это никак влиять не должно. Меня интересует корень проблемы, а не какая-нибудь магическая манипуляция, которая ее обойдет. Придумать костыль я могу без проблем.
 

rkit

New member
посмотрите исходники
То есть вы утверждаете, что они не поленились в readme написать о длине имени файла, о том, что фс не годится для реалтайма и для файловых систем больше 128 МБ, но забыли написать о том, что можно открыть ТОЛЬКО ОДИН ФАЙЛ?
Не надо выставлять себя дураком.
 

rkit

New member
Вы из воинствующих дилетантов?
Вы внимательно прочитали что я написал?
Я вообще ничего не утверждал, а сообщил результат своего изучения исходников и чтения документации.
Вы можете просто игнорировать мое мнение либо изучить софт и сформировать свое.
Прочитал и поржал. Если вам нечего утверждать, то не надо тратить мое время. Более того, в документации, которую вы якобы читали, прямым текстом советуют файлы НЕ ЗАКРЫВАТЬ:
There is a quick way not wasting time opening files - do not close them. If you have but a few files that must be accessed quickly, and have the memory for it, you can simply open those files in the beginning and never close them.

Opened files are tracked - if the file is moved, the file descriptor is updated internally. Actually, it is valid to open the same file in multiple file descriptors. They will all be updated upon changes to the spi flash.
А я предлагал не выставлять себя дураком.

И закрывать файл я пробовал, для воинствующих "недилетантов".


Мне нужно ваше чтение исходников во сне и прочее. Мне нужен человек, который реально сталкивался с такой проблемой. Если вы не сталкивались, то не тратьте мое время.
 

Юрий Ботов

Moderator
Команда форума
Зачем долго спорить просто проверьте сами:
FSInfo fs_info;
SPIFFS.info(fs_info);
где
struct FSInfo {
size_t totalBytes;
size_t usedBytes;
size_t blockSize;
size_t pageSize;
size_t maxOpenFiles;
size_t maxPathLength;
};
и соответственно:
maxOpenFiles — max number of files which may be open simultaneously

И не забудьте что есть SPIFFS_errno в которой можно посмотреть код ошибки если она была...
 

pvvx

Активный участник сообщества
maxOpenFiles — max number of files which may be open simultaneously
Значит должен держать описанное кол-во всегда открытых файлов. В чем беда там поставить 32 шт к примеру? Кривой и неоптимальный код? :)
Примерная историю, почему на ESP используется самый худший вариант файловой системы из имеющихся вы не исследовали? :)
Она совершенно не подходит к политике SDK и вообще для многих более менее современных MCU. Тут уже ничего не поделать - всё в ESP используется только такое кривое, из-за начальной лени "портировщиков". На то он и ESP :)
Сравнение характеристик SPIFFS с простым кольцевым буфером, записываемым, к примеру, пачками по 32 байта с маркером, показывает, что SPIFFS работает медленнее и требует больше ресурсов по RAM и Flash. Особенно по объему хранения в Flash. У него показатель не более 2/3 полезной информации от объема и при таком заполнении (или после обработки объема к 2/3 объема) он становиться неработоспособным – время открытия файла превышает время полного считывания всей Flash:)
 
Последнее редактирование:

Сергей_Ф

Moderator
Команда форума
Ради эксперимента открыл 5 файлов на запись, записал в каждый по очереди миллис, закрыл все и прочитал содержимое директории и всех файлов в ней - ничего не пропало.
А вот если файл на запись не закрывать, то прочитать его нельзя. И в листинге его может не быть.
 

pvvx

Активный участник сообщества
Ради эксперимента открыл 5 файлов на запись, записал в каждый по очереди миллис, закрыл все и прочитал содержимое директории и всех файлов в ней - ничего не пропало.
А вот если файл на запись не закрывать, то прочитать его нельзя. И в листинге его может не быть.
Т.е. нет совместного доступа к файлу?
Если в задаче открыть 10 файлов с одним именем, то это проходит? :eek:
 

Сергей_Ф

Moderator
Команда форума
@pvvx если открыт только на запись - нет. Надо открывать с опцией 'а', тогда есть. И не забывать закрывать если пишешь, а то при сбоях всё может потерять :)
 
Последнее редактирование:

Сергей_Ф

Moderator
Команда форума
@pvvx я не менял настройки ФС, максимальное число файлов у меня 5. Если читать, то ничего страшного - читай хоть 20 , только открой на чтение перед этим. Но одновременно, все равно только 5. Но можно не закрывать.
А если на запись и не закрыть - бяка выходит.
 

pvvx

Активный участник сообщества
@pvvx я не менял настройки ФС, максимальное число файлов у меня 5. Если читать, то ничего страшного - читай хоть 20 , только открой на чтение перед этим. Но одновременно, все равно только 5. Но можно не закрывать.
А если на запись и не закрыть - бяка выходит.
А почему? Открыли хоть 100 одноименных (в передел установок) и пишите в них. В файле будет каша - почередность вывода в эти файлы. Если какая задача закроет файл, то он должен сохраниться. Другие могут продолжать писать в этот файл. Закрытие - это всего объявление в каталоге события... для других открывающих этот файл оно ничего не значит и размер его определяют другие открывшие и пишущие в него. По другому написать сложно и не требуется.
 

Сергей_Ф

Moderator
Команда форума
@pvvx я не анализировал , почему. Просто провел тест в Ардуино ИДЕ. Так у меня вышло.
Если файл не закрыт на запись, то прочитать его нельзя, даже если попытаться открыть на чтение перед этим. И в листинге его может не быть.
Я даже ошибки не смотрел.
 

pvvx

Активный участник сообщества
@pvvx я не анализировал , почему. Просто провел тест в Ардуино ИДЕ. Так у меня вышло.
Если файл не закрыт на запись, то прочитать его нельзя, даже если попытаться открыть на чтение перед этим. И в листинге его может не быть.
Я даже ошибки не смотрел.
Это значит, что каталог не обновляется при открытии нового файла. Т.е. логическая ошибка.
Итог - решение данной темы. Ошибка (очередная) в SPIFFS -> делать примочку, или править, или обходить эту ошибку.
 

nikolz

Well-known member
Это значит, что каталог не обновляется при открытии нового файла. Т.е. логическая ошибка.
Итог - решение данной темы. Ошибка (очередная) в SPIFFS -> делать примочку, или править, или обходить эту ошибку.
вроде бы В SPIFFS нет каталога, там сектора содержат имя файла.
 
Наблюдал еще худшую ситуацию, сделал файл для сохранения текущих данных (закрывал по окончании записи), обновлял его раз в час.
через ~ месяц система рухнула. Форматировал, повторил проект, через месяц опять рухнула.
Теперь использую RTC MEM c батарейкой.
 

rkit

New member
Да. Когда начал тестировать на объеме - 2 записи в секунду, оно стало портить фс. Придется писать логи в сеть.
 
Сверху Снизу