Ошибка сохранения SPIFFS на ESP8266 - только после 3-й записи

esp8266 spiffs

EDIT1 - Это явление возникает только после перезагрузки с помощью кнопки или ESP.reboot()

Я постараюсь сделать свой вопрос более сфокусированным:

  1. У меня есть библиотека, которая сохраняет события журнала в SPIFFS.

  2. Начиная с 3 - й записи (в следующем примере-записи часов эпохи), она каким-то образом неправильно экономится (переход к Take-4 ниже).

  3. Следующий код является примером использования только соответствующих функций из этой библиотеки.

Краткое объяснение:

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);
}

, 👍0

Обсуждение

Комментарии не предназначены для расширенного обсуждения; этот разговор был [перенесен на chat](https://chat.stackexchange.com/rooms/128456/discussion-on-question-by-guy-d-error-saving-spiffs-on-esp8266-only-after-3r)., @Juraj


1 ответ


Лучший ответ:

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 ~~~
  1. @Питер, в комментариях , упомянутых в связи с проблемой github, указал, что существует известная проблема, связанная с перезагрузками и достоверностью хранимых данных. Проблема была решена с помощью файла.flush() - но это решение не решило проблему

  2. При поиске ядра ESP8266 он указал на ошибки, касающиеся сохраненных данных и их достоверности

  3. только после обновления LittleFS для всех экземпляров в коде (каким-то образом, когда он был проверен как часть предложения Питера, только несколько экземпляров были изменены из SPIFFS), решена эта проблема. файла нет.требуется сброс() или задержка ().

,