Ошибка сохранения SPIFFS на ESP8266 - только после 3-й записи
EDIT1 - Это явление возникает только после перезагрузки с помощью кнопки или ESP.reboot()
Я постараюсь сделать свой вопрос более сфокусированным:
У меня есть библиотека, которая сохраняет события журнала в SPIFFS.
Начиная с 3 - й записи (в следующем примере-записи часов эпохи), она каким-то образом неправильно экономится (переход к Take-4 ниже).
Следующий код является примером использования только соответствующих функций из этой библиотеки.
Краткое объяснение:
T
держит часы эпохи, которые сохраняют их сразу после загрузки.
функция записи(const char *сообщение, ТЕПЕРЬ bool)
- получает сообщение для хранения и логическое значение, если оно должно быть сохранено немедленно, а не отложено (отложенное сохранение реализовано только в библиотеке, в то время как здесь оно сохраняется мгновенно).
void _write2file()
записывает буфер в SPIFFS.
int getnumlines()
возвращает количество сохраненных записей (ищет символы _EOL). В приведенном ниже коде он действует только как информация, которая служит для отображения проблемы, в то время как при использовании в коде реальной библиотеки он ограничивает количество записей в журнале.
void rawPrintfile()
печатает содержимое журнала в удобочитаемом для человека виде.
И последнее, единственная функция, которая не принадлежит библиотеке, void insert_log_entry()
, просто введите запись в журнале (всегда одну и ту же после перезагрузки).
Дубль 1-После загрузки скетча вы получаете следующий результат:
19:58:00.125 -> add buffer #0: 1234567890
19:58:00.191 -> total Lines before: 0
19:58:00.191 -> entries in buffer: 1
19:58:00.257 -> ~~~ Saved in /logfile.txt ~~~
19:58:00.257 -> row #0 {1234567890}
19:58:00.257 -> ~~~ EOF ~~~
Пояснение: в буфере была 1 запись, ранее записей не было, и распечатка содержимого файла. Пока все в порядке!
Сделайте 2 нажатия кнопки перезагрузки, и результаты будут следующими:
19:58:07.747 -> Start!
19:58:07.814 -> add buffer #0: 1234567890
19:58:07.814 -> total Lines before: 1
19:58:07.814 -> entries in buffer: 1
19:58:07.814 -> ~~~ Saved in /logfile.txt ~~~
19:58:07.814 -> row #0 {1234567890}
19:58:07.814 -> row #1 {1234567890}
19:58:07.814 -> ~~~ EOF ~~~
Пояснение:снова 1 запись в буфере, 1 запись в журнале и распечатка 2 записей.
Возьмите 3 Повторное нажатие кнопки перезагрузки приводит к следующим результатам:
19:58:10.167 -> Start!
19:58:10.200 -> add buffer #0: 1234567890
19:58:10.200 -> total Lines before: 2
19:58:10.233 -> entries in buffer: 1
19:58:10.233 -> ~~~ Saved in /logfile.txt ~~~
19:58:10.233 -> row #0 {1234567890}
19:58:10.233 -> row #1 {1234567890}
19:58:10.233 -> row #2 {1234567890}
19:58:10.233 -> ~~~ EOF ~~~
Пояснение: то же самое, но теперь сохранены 3 записи.
Дубль 4!!!
19:58:11.194 -> Start!
19:58:11.227 -> add buffer #0: 1234567890
19:58:11.227 -> total Lines before: 2
19:58:11.260 -> entries in buffer: 1
19:58:11.260 -> ~~~ Saved in /logfile.txt ~~~
19:58:11.260 -> row #0 {1234567890}
19:58:11.260 -> row #1 {1234567890}
19:58:11.260 -> row #2 {12345678⸮⸮⸮1234567890}
19:58:11.260 -> ~~~ EOF ~~~
Пояснение: Теперь вот нерешенная ошибка - 4-я запись смешивается с 3-й, в результате чего в ней насчитывается только 2 записи (где должно было быть 3), и строка № 2 теперь смешана.
С целью - я упростил код, чтобы сосредоточиться на самой проблеме , в которой я не могу найти основную причину этой ошибки (скорее, показ всей библиотеки, состоящей из функции отложенного сохранения и удаления строки, когда журнал заполняется).
`
#include <FS.h>
unsigned long T = 1234567890;
char *_logfilename = "/logfile.txt";
int _buff_i = 0;
#define TEMP_LOG_SIZE 10
#define TEMP_LOG_LEN 150
int _logSize = TEMP_LOG_SIZE; // записи
int _logLength = TEMP_LOG_LEN; // символы в каждой записи
char _logBuffer[TEMP_LOG_SIZE][TEMP_LOG_LEN]; // Временный буфер для отложенной записи
const char _EOL = '\r';
unsigned long lastUpdate = 0;
void insert_log_entry()
{
char a[25];
sprintf(a, "%d", T);
write(a, true);
}
void rawPrintfile()
{
int row_counter = 0;
bool new_line = true;
File file = SPIFFS.open(_logfilename, "r");
if (!file)
{
Serial.println("Не удалось открыть файл для чтения");
}
Serial.print("~~~ Saved in ");
Serial.print(_logfilename);
Serial.println(" ~~~");
while (file.available())
{
if (new_line)
{
Serial.print("row #");
Serial.print(row_counter++);
Serial.print(" {");
new_line = false;
}
char tt = file.read();
if (tt == _EOL)
{
new_line = true;
Serial.println("}");
}
else
{
Serial.print(tt);
}
}
file.close();
Serial.println("~~~ EOF ~~~");
}
int getnumlines()
{
int row_counter = 0;
File file = SPIFFS.open(_logfilename, "r");
if (file)
{
while (file.available())
{
char tt = file.read();
if (tt == _EOL)
{
row_counter++;
}
}
}
file.close();
return row_counter;
}
void write(const char *message, bool NOW)
{
sprintf(_logBuffer[_buff_i], "%s%c", message, _EOL);
Serial.print("add buffer #");
Serial.print(_buff_i);
Serial.print(": ");
Serial.println(_logBuffer[_buff_i]);
_buff_i++;
lastUpdate = millis();
if (NOW == true)
{
_write2file();
}
}
void _write2file()
{
int num_lines = getnumlines();
Serial.print("всего строк до: ");
Serial.println(num_lines);
Serial.print("записи в буфере: ");
Serial.println(_buff_i);
File file1 = SPIFFS.open(_logfilename, "a");
if (!file1)
{
Serial.println("Не удалось открыть файл для добавления");
}
else
{
for (int x = 0; x < _buff_i; x++)
{
file1.print(_logBuffer[x]);
}
_buff_i = 0;
lastUpdate = 0;
}
file1.close();
}
void setup()
{
Serial.begin(115200);
Serial.println("\n\nStart!");
SPIFFS.begin();
insert_log_entry();
rawPrintfile();
}
void loop()
{
delay(50);
}
@Guy . D, 👍0
Обсуждение1 ответ
Лучший ответ:
Ну , получить ответ было непросто.
- Это происходит только после перезагрузки ( кнопка или
, особенно, сброс ()
), каким - то образом после 2-й попытки, каждый раз-получая это ( см.Это
):
19:58:11.194 -> Start! 19:58:11.227 -> add buffer #0: 1234567890 19:58:11.227 -> total Lines before: 2 19:58:11.260 -> entries in buffer: 1 19:58:11.260 -> ~~~ Saved in /logfile.txt ~~~ 19:58:11.260 -> row #0 {1234567890} 19:58:11.260 -> row #1 {1234567890} 19:58:11.260 -> row #2 {12345678⸮⸮⸮1234567890} <----- THIS ---- 19:58:11.260 -> ~~~ EOF ~~~
@Питер, в комментариях , упомянутых в связи с проблемой github, указал, что существует известная проблема, связанная с перезагрузками и достоверностью хранимых данных. Проблема была решена с помощью
файла.flush()
- но это решение не решило проблемуПри поиске ядра ESP8266 он указал на ошибки, касающиеся сохраненных данных и их достоверности
только после обновления
LittleFS
для всех экземпляров в коде (каким-то образом, когда он был проверен как часть предложения Питера, только несколько экземпляров были изменены изSPIFFS
), решена эта проблема.файла нет.требуется сброс()
илизадержка ()
.
- ОТА-программа SPIFFS на ESP8266
- Как записать и прочитать из файла SPIFFS как данные объекта на ESP8266
- Как сохранить структуру в файле?
- Любой способ использовать DMA для передачи данных на SD - карту в ESP8266
- Сбой при обслуживании файлов статической ширины ESP8266WebServer
- Где хранить критические данные в ситуации отключения электроэнергии на ESP8266
- как заставить этот код работать со spiffs?
- Как динамически реагировать с помощью файлов, содержащих шаблоны?
Комментарии не предназначены для расширенного обсуждения; этот разговор был [перенесен на chat](https://chat.stackexchange.com/rooms/128456/discussion-on-question-by-guy-d-error-saving-spiffs-on-esp8266-only-after-3r)., @Juraj