fix(flash): increase INT_WDT timeout, enable littlefs wdt reset and thread safety
All checks were successful
ESP32 Build & Release / build (push) Successful in 1m11s

This commit is contained in:
2026-09-12 16:43:02 +02:00
parent 4a5b058c1a
commit fc05fa2f8b
4 changed files with 74 additions and 12 deletions

View File

@@ -8,6 +8,8 @@
#include <sys/stat.h>
#include <sys/unistd.h>
#include <dirent.h>
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "esp_log.h"
#include "esp_littlefs.h"
#include "cJSON.h"
@@ -17,11 +19,32 @@ static const char *TAG = "storage";
#define STORAGE_PARTITION_LABEL "storage"
static SemaphoreHandle_t s_storage_mux = NULL;
static void storage_lock(void)
{
if (s_storage_mux == NULL) {
s_storage_mux = xSemaphoreCreateRecursiveMutex();
}
if (s_storage_mux != NULL) {
xSemaphoreTakeRecursive(s_storage_mux, portMAX_DELAY);
}
}
static void storage_unlock(void)
{
if (s_storage_mux != NULL) {
xSemaphoreGiveRecursive(s_storage_mux);
}
}
bool storage_file_exists(const char *path)
{
storage_lock();
struct stat st;
return (stat(path, &st) == 0) && S_ISREG(st.st_mode);
bool exists = (stat(path, &st) == 0) && S_ISREG(st.st_mode);
storage_unlock();
return exists;
}
esp_err_t storage_read_text(const char *path, char **out_buf, size_t *out_len)
@@ -29,21 +52,25 @@ esp_err_t storage_read_text(const char *path, char **out_buf, size_t *out_len)
if (out_buf == NULL || out_len == NULL) {
return ESP_ERR_INVALID_ARG;
}
storage_lock();
*out_buf = NULL;
*out_len = 0;
FILE *f = fopen(path, "rb");
if (f == NULL) {
storage_unlock();
return ESP_ERR_NOT_FOUND;
}
if (fseek(f, 0, SEEK_END) != 0) {
fclose(f);
storage_unlock();
return ESP_FAIL;
}
long size = ftell(f);
if (size < 0) {
fclose(f);
storage_unlock();
return ESP_FAIL;
}
rewind(f);
@@ -51,6 +78,7 @@ esp_err_t storage_read_text(const char *path, char **out_buf, size_t *out_len)
char *buf = malloc((size_t)size + 1);
if (buf == NULL) {
fclose(f);
storage_unlock();
return ESP_ERR_NO_MEM;
}
@@ -58,11 +86,13 @@ esp_err_t storage_read_text(const char *path, char **out_buf, size_t *out_len)
fclose(f);
if (rd != (size_t)size) {
free(buf);
storage_unlock();
return ESP_FAIL;
}
buf[rd] = '\0';
*out_buf = buf;
*out_len = rd;
storage_unlock();
return ESP_OK;
}
@@ -76,27 +106,34 @@ esp_err_t storage_write_text(const char *path, const char *text)
}
snprintf(tmp, sizeof(tmp), "%s.tmp", path);
storage_lock();
FILE *f = fopen(tmp, "wb");
if (f == NULL) {
ESP_LOGE(TAG, "open %s failed", tmp);
storage_unlock();
return ESP_FAIL;
}
size_t wr = fwrite(text, 1, strlen(text), f);
if (wr != strlen(text) || fflush(f) != 0 || fclose(f) != 0) {
ESP_LOGE(TAG, "write %s failed", tmp);
remove(tmp);
storage_unlock();
return ESP_FAIL;
}
remove(path);
if (rename(tmp, path) != 0) {
ESP_LOGE(TAG, "rename %s -> %s failed", tmp, path);
remove(tmp);
storage_unlock();
return ESP_FAIL;
}
storage_unlock();
return ESP_OK;
}
esp_err_t storage_manager_bind_uid(const char *uid, const char *card_name)
{
storage_lock();
cJSON *root = NULL;
char *existing = NULL;
size_t existing_len = 0;
@@ -111,6 +148,7 @@ esp_err_t storage_manager_bind_uid(const char *uid, const char *card_name)
root = cJSON_CreateObject();
}
if (root == NULL) {
storage_unlock();
return ESP_ERR_NO_MEM;
}
@@ -133,6 +171,7 @@ esp_err_t storage_manager_bind_uid(const char *uid, const char *card_name)
esp_err_t ret = out ? storage_write_text(STORAGE_MAPPINGS, out) : ESP_ERR_NO_MEM;
free(out);
cJSON_Delete(root);
storage_unlock();
return ret;
}
@@ -141,6 +180,7 @@ esp_err_t storage_manager_unbind_uid(const char *uid)
if (uid == NULL || uid[0] == '\0') {
return ESP_ERR_INVALID_ARG;
}
storage_lock();
char *existing = NULL;
size_t existing_len = 0;
cJSON *root = NULL;
@@ -152,11 +192,13 @@ esp_err_t storage_manager_unbind_uid(const char *uid)
if (root == NULL || !cJSON_IsObject(root)) {
if (root) cJSON_Delete(root);
storage_unlock();
return ESP_ERR_NOT_FOUND;
}
if (!cJSON_HasObjectItem(root, uid)) {
cJSON_Delete(root);
storage_unlock();
return ESP_ERR_NOT_FOUND;
}
@@ -174,16 +216,19 @@ esp_err_t storage_manager_unbind_uid(const char *uid)
esp_err_t ret = out ? storage_write_text(STORAGE_MAPPINGS, out) : ESP_ERR_NO_MEM;
free(out);
cJSON_Delete(root);
storage_unlock();
return ret;
}
esp_err_t storage_manager_lookup_name(const char *uid, char **out)
{
*out = NULL;
storage_lock();
char *buf = NULL;
size_t len = 0;
if (storage_read_text(STORAGE_MAPPINGS, &buf, &len) != ESP_OK || buf == NULL) {
free(buf);
storage_unlock();
return ESP_ERR_NOT_FOUND;
}
@@ -191,6 +236,7 @@ esp_err_t storage_manager_lookup_name(const char *uid, char **out)
free(buf);
if (root == NULL || !cJSON_IsObject(root)) {
if (root) cJSON_Delete(root);
storage_unlock();
return ESP_ERR_NOT_FOUND;
}
@@ -203,6 +249,7 @@ esp_err_t storage_manager_lookup_name(const char *uid, char **out)
}
}
cJSON_Delete(root);
storage_unlock();
return ret;
}
@@ -269,8 +316,10 @@ esp_err_t storage_manager_count_cached(int *json_count, int *jpg_count)
*json_count = 0;
*jpg_count = 0;
storage_lock();
DIR *d = opendir(STORAGE_CARDS_DIR);
if (d == NULL) {
storage_unlock();
return ESP_OK;
}
struct dirent *entry;
@@ -285,11 +334,13 @@ esp_err_t storage_manager_count_cached(int *json_count, int *jpg_count)
}
}
closedir(d);
storage_unlock();
return ESP_OK;
}
esp_err_t storage_manager_clear_all_cards(bool reset_mappings)
{
storage_lock();
DIR *d = opendir(STORAGE_CARDS_DIR);
if (d != NULL) {
struct dirent *entry;
@@ -309,5 +360,6 @@ esp_err_t storage_manager_clear_all_cards(bool reset_mappings)
storage_write_text(STORAGE_MAPPINGS, "{\n}\n");
ESP_LOGI(TAG, "Reset %s to empty", STORAGE_MAPPINGS);
}
storage_unlock();
return ESP_OK;
}