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
All checks were successful
ESP32 Build & Release / build (push) Successful in 1m11s
This commit is contained in:
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user