Save History Sync on flash, still some issues in deleting previous file

This commit is contained in:
Emanuele Trabattoni
2026-04-08 10:27:18 +02:00
parent 481f12f526
commit 07eb06f67b
5 changed files with 59 additions and 42 deletions

View File

@@ -2,5 +2,5 @@
# Name, Type, SubType, Offset, Size # Name, Type, SubType, Offset, Size
nvs, data, nvs, 0x9000, 0x4000 nvs, data, nvs, 0x9000, 0x4000
phy_init, data, phy, 0xd000, 0x1000 phy_init, data, phy, 0xd000, 0x1000
factory, app, factory, 0x10000, 0x5F0000 factory, app, factory, 0x10000, 0x300000
spiffs, data, spiffs, 0x600000, 0xA00000 spiffs, data, spiffs, 0x310000, 0xCF0000
1 # ESP32 Partition Table
2 # Name, Type, SubType, Offset, Size
3 nvs, data, nvs, 0x9000, 0x4000
4 phy_init, data, phy, 0xd000, 0x1000
5 factory, app, factory, 0x10000, 0x5F0000 factory, app, factory, 0x10000, 0x300000
6 spiffs, data, spiffs, 0x600000, 0xA00000 spiffs, data, spiffs, 0x310000, 0xCF0000

View File

@@ -47,7 +47,7 @@ lib_deps = ${env:esp32-s3-devkitc1-n16r8.lib_deps}
;Upload protocol configuration ;Upload protocol configuration
upload_protocol = esptool upload_protocol = esptool
upload_port = COM4 upload_port = COM8
upload_speed = 921600 upload_speed = 921600
;Monitor configuration ;Monitor configuration

View File

@@ -1,45 +1,51 @@
#include "datasave.h" #include "datasave.h"
static const size_t min_free = 1024 * 1024; // minimum free space in SPIFFS to allow saving history (1MB) static const size_t min_free = 1024 * 1024; // minimum free space in SPIFFS to allow saving history (1MB)
static bool first_save = true; // flag to indicate if this is the first save (to write header)
void save_history(const PSRAMVector<ignitionBoxStatus> &history, const std::filesystem::path &file_path) void saveHistoryTask(void *pvParameters)
{
const auto *params = static_cast<dataSaveParams *>(pvParameters);
const auto &history = *params->history;
const auto &file_path = params->file_path;
if (!params) {
LOG_ERROR("Invalid parameters for saveHistoryTask");
return;
}
LOG_DEBUG("Starting saving: ", file_path.c_str());
save_history(history, file_path);
vTaskDelete(NULL);
}
void save_history(const PSRAMVector<ignitionBoxStatus> &history, const std::filesystem::path &file_name)
{ {
// Initialize SPIFFS // Initialize SPIFFS
if (!SPIFFS.begin(true)) auto spiffs_guard = SPIFFSGuard(); // use RAII guard to ensure SPIFFS is properly mounted and unmounted
{
LOG_ERROR("Failed to mount SPIFFS");
LOG_ERROR("5 seconds to restart...");
vTaskDelay(pdMS_TO_TICKS(5000));
esp_restart();
}
LOG_INFO("SPIFFS mounted successfully");
if (SPIFFS.totalBytes() - SPIFFS.usedBytes() < min_free ) // check if at least 1MB is free for saving history if (SPIFFS.totalBytes() - SPIFFS.usedBytes() < min_free ) // check if at least 1MB is free for saving history
{ {
LOG_ERROR("Not enough space in SPIFFS to save history"); LOG_ERROR("Not enough space in SPIFFS to save history");
return; return;
} }
std::filesystem::path to_save = file_path; std::filesystem::path file_path = file_name;
if (file_path.root_path() != "/spiffs") if (file_name.root_path() != "/spiffs")
to_save = std::filesystem::path("/spiffs") / file_path; file_path = std::filesystem::path("/spiffs") / file_name;
auto save_flags = std::ios::out; auto save_flags = std::ios::out;
if (first_save && SPIFFS.exists(to_save.c_str())) if (first_save && SPIFFS.exists(file_path.c_str()))
{ {
first_save = false; first_save = false;
save_flags |= std::ios::trunc; // overwrite existing file save_flags |= std::ios::trunc; // overwrite existing file
SPIFFS.remove(to_save.c_str()); // ensure file is removed before saving to avoid issues with appending to existing file in SPIFFS SPIFFS.remove(file_path.c_str()); // ensure file is removed before saving to avoid issues with appending to existing file in SPIFFS
LOG_INFO("Saving history to SPIFFS, new file: ", to_save.c_str()); LOG_INFO("Saving history to SPIFFS, new file:", file_path.c_str());
} }
else else
{ {
save_flags |= std::ios::app; // append to new file save_flags |= std::ios::app; // append to new file
LOG_INFO("Saving history to SPIFFS, appending to existing file: ", to_save.c_str()); LOG_INFO("Saving history to SPIFFS, appending to existing file:", file_path.c_str());
} }
std::ofstream ofs(to_save, save_flags); std::ofstream ofs(file_path, save_flags);
if (ofs.fail()) if (ofs.fail())
{ {
LOG_ERROR("Failed to open file for writing"); LOG_ERROR("Failed to open file for writing");
@@ -50,9 +56,9 @@ void save_history(const PSRAMVector<ignitionBoxStatus> &history, const std::file
if (first_save) if (first_save)
{ {
ofs << "TS,\ ofs << "TS,\
EVENTS_12,DLY_12,STAT_12,V_12_1,V_12_2,V_12_3,V_12_4,IGNITION_MODE_12,\ EVENTS_12,DLY_12,STAT_12,V_12_1,V_12_2,V_12_3,V_12_4,IGNITION_MODE_12,\
EVENTS_34,DLY_34,STAT_34,V_34_1,V_34_2,V_34_3,V_34_4,IGNITION_MODE_34,\ EVENTS_34,DLY_34,STAT_34,V_34_1,V_34_2,V_34_3,V_34_4,IGNITION_MODE_34,\
ENGINE_RPM,ADC_READTIME,N_QUEUE_ERRORS" << std::endl; ENGINE_RPM,ADC_READTIME,N_QUEUE_ERRORS" << std::endl;
ofs.flush(); ofs.flush();
} }
@@ -84,5 +90,4 @@ void save_history(const PSRAMVector<ignitionBoxStatus> &history, const std::file
ofs.close(); ofs.close();
LOG_INFO("Ignition A history saved to SPIFFS, records written: ", history.size()); LOG_INFO("Ignition A history saved to SPIFFS, records written: ", history.size());
SPIFFS.end(); // unmount SPIFFS to ensure data is written and avoid corruption on next mount
} }

View File

@@ -1,4 +1,5 @@
#pragma once #pragma once
#define DEBUGLOG_DEFAULT_LOG_LEVEL_INFO
// System Includes // System Includes
#include <Arduino.h> #include <Arduino.h>
@@ -14,6 +15,7 @@
const uint32_t max_history = 256; const uint32_t max_history = 256;
const bool SAVE_HISTORY_TO_SPIFFS = true; // Set to true to enable saving history to SPIFFS, false to disable const bool SAVE_HISTORY_TO_SPIFFS = true; // Set to true to enable saving history to SPIFFS, false to disable
static bool first_save = true; // flag to indicate if this is the first save (to write header)
struct dataSaveParams struct dataSaveParams
{ {
@@ -21,18 +23,26 @@ struct dataSaveParams
const std::filesystem::path file_path; const std::filesystem::path file_path;
}; };
class SPIFFSGuard
{
public:
SPIFFSGuard() {
if (!SPIFFS.begin(true)) {
LOG_ERROR("Failed to mount SPIFFS");
LOG_ERROR("5 seconds to restart...");
vTaskDelay(pdMS_TO_TICKS(5000));
esp_restart();
}
LOG_DEBUG("SPIFFS mounted successfully");
}
~SPIFFSGuard() {
SPIFFS.end();
LOG_DEBUG("SPIFFS unmounted successfully");
}
};
// Task and function declarations
void saveHistoryTask(void *pvParameters);
void save_history(const PSRAMVector<ignitionBoxStatus> &history, const std::filesystem::path& file_path); void save_history(const PSRAMVector<ignitionBoxStatus> &history, const std::filesystem::path& file_path);
static void saveHistoryTask(void *pvParameters)
{
const auto *params = static_cast<dataSaveParams *>(pvParameters);
const auto &history = *params->history;
const auto &file_path = params->file_path;
if (!params) {
LOG_ERROR("Invalid parameters for saveHistoryTask");
return;
}
LOG_INFO("Starting saving: ", file_path.c_str());
save_history(history, file_path);
//vTaskDelete(NULL);
}

View File

@@ -189,10 +189,10 @@ void loop()
auto *temp = active_history; auto *temp = active_history;
active_history = writable_history; // switch active and writable buffers active_history = writable_history; // switch active and writable buffers
writable_history = temp; // ensure writable_history points to the buffer we just filled writable_history = temp; // ensure writable_history points to the buffer we just filled
dataSaveParams save_params{ dataSaveParams save_params {
.history = writable_history, .history = writable_history,
.file_path = "ignition_history.csv"}; .file_path = "ignition_history.csv"};
saveHistoryTask(&save_params); // directly call the save task function to save without delay, since we already switched buffers and writable_history is now empty and ready for new data save_history(*writable_history, "ignition_history.csv"); // directly call the save task function to save without delay, since we already switched buffers and writable_history is now empty and ready for new data
// if (SAVE_HISTORY_TO_SPIFFS) // if (SAVE_HISTORY_TO_SPIFFS)
// if (pdFAIL == // if (pdFAIL ==
// xTaskCreatePinnedToCore( // xTaskCreatePinnedToCore(
@@ -220,10 +220,12 @@ void loop()
Serial.println("Waiting for data... "); Serial.println("Waiting for data... ");
if (!partial_save && counter > 0) // if timeout occurs but we have unsaved data, save it before next timeout if (!partial_save && counter > 0) // if timeout occurs but we have unsaved data, save it before next timeout
{ {
active_history->resize(counter); // resize active history to actual number of records received to avoid saving empty records
save_history(*active_history, "ignition_history.csv");
active_history->resize(max_history); // resize back to max history size for next data cycle
counter = 0; // reset counter after saving counter = 0; // reset counter after saving
partial_save = true; partial_save = true;
Serial.println("Saving history to SPIFFS..."); first_save = true;
save_history(*active_history, "ignition_history.csv");
} }
delay(500); delay(500);
} }