update session access lock
This commit is contained in:
@@ -1106,13 +1106,7 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
|
||||
debug_printf("Factory reset: clearing flash "
|
||||
"and rebooting\n");
|
||||
unsafe {
|
||||
lfs_remove_file("game_mode");
|
||||
lfs_remove_file("mic_vol");
|
||||
lfs_remove_file("dac_vol");
|
||||
lfs_remove_file("footstep");
|
||||
lfs_remove_file("monitor_sw");
|
||||
lfs_remove_file("mic_mute");
|
||||
lfs_remove_file("hp_mute");
|
||||
lfs_format_all();
|
||||
}
|
||||
|
||||
led_on(&led_ctx, LED_MUSIC);
|
||||
|
||||
@@ -161,6 +161,7 @@ int eq_flash_init(void) {
|
||||
while (retry_count < 3 && lfs_init_result != 0) {
|
||||
lfs_init_result = lfs_init();
|
||||
if (lfs_init_result != 0) {
|
||||
lfs_deinit(); // 释放session锁,避免下次循环自死锁
|
||||
retry_count++;
|
||||
DPRINTF("Failed to initialize LFS, retry %d/3\n", retry_count);
|
||||
if (retry_count < 3) {
|
||||
@@ -252,10 +253,16 @@ int eq_flash_load_mode(uint8_t mode) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lfs_init() != 0) {
|
||||
lfs_deinit();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 获取当前采样率的EQ数组指针
|
||||
eq_mode_data_t (*eq_array)[NUM_EQ_MODES][NUM_EQ_CHANS] = get_eq_array_ptr(g_eq_sample_rate);
|
||||
if (!eq_array) {
|
||||
DPRINTF(" Error: Failed to get EQ array for current sample rate %lu\n", (unsigned long)g_eq_sample_rate);
|
||||
lfs_deinit();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -378,6 +385,7 @@ int eq_flash_load_mode(uint8_t mode) {
|
||||
DPRINTF(" Successfully loaded EQ parameters for mode %d, channel %d\n", mode, ch);
|
||||
}
|
||||
|
||||
lfs_deinit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -729,6 +737,11 @@ int eq_save_dirty_params(void) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lfs_init() != 0) {
|
||||
lfs_deinit();
|
||||
return -1;
|
||||
}
|
||||
|
||||
//DPRINTF(" Single param database count: %d\n", single_param_database.param_count);
|
||||
|
||||
int saved_count = 0;
|
||||
@@ -769,6 +782,7 @@ int eq_save_dirty_params(void) {
|
||||
if (saved_count > 0) {
|
||||
DPRINTF(" Saved %d dirty single parameters\n", saved_count);
|
||||
}
|
||||
lfs_deinit();
|
||||
return 0;
|
||||
}
|
||||
/**
|
||||
@@ -787,14 +801,21 @@ int eq_save_dirty_gain(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lfs_init() != 0) {
|
||||
lfs_deinit();
|
||||
return -1;
|
||||
}
|
||||
|
||||
DPRINTF(" Saving dirty gain\n");
|
||||
// 使用新的独立保存函数
|
||||
if (eq_save_gain() == 0) {
|
||||
gain_dirty = 0; // 只清除增益脏标志
|
||||
DPRINTF(" Successfully saved gain\n");
|
||||
lfs_deinit();
|
||||
return 0;
|
||||
} else {
|
||||
DPRINTF(" Error: Failed to save gain\n");
|
||||
lfs_deinit();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -814,6 +835,11 @@ int eq_save_dirty_names(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lfs_init() != 0) {
|
||||
lfs_deinit();
|
||||
return -1;
|
||||
}
|
||||
|
||||
DPRINTF(" Saving dirty mode names\n");
|
||||
// 使用新的独立保存函数,逐个保存每个用户模式的name
|
||||
int saved_count = 0;
|
||||
@@ -833,12 +859,15 @@ int eq_save_dirty_names(void) {
|
||||
|
||||
if (saved_count > 0) {
|
||||
DPRINTF(" Successfully saved %d mode name(s), skipped %d\n", saved_count, skipped_count);
|
||||
lfs_deinit();
|
||||
return 0;
|
||||
} else if (skipped_count > 0) {
|
||||
DPRINTF(" All mode names skipped (same as default or empty), %d skipped\n", skipped_count);
|
||||
lfs_deinit();
|
||||
return 0; // 跳过是正常的,不算错误
|
||||
} else {
|
||||
DPRINTF(" Error: Failed to save mode names\n");
|
||||
lfs_deinit();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -989,6 +1018,8 @@ int eq_save_name(uint8_t mode) {
|
||||
* @return 0: 成功, -1: 失败
|
||||
*/
|
||||
int eq_save_gain_and_names(void) {
|
||||
if (lfs_init() != 0) { lfs_deinit(); return -1; }
|
||||
|
||||
int ret = 0;
|
||||
|
||||
// 保存gain
|
||||
@@ -1005,6 +1036,7 @@ int eq_save_gain_and_names(void) {
|
||||
// result == 1 表示跳过,这是正常的
|
||||
}
|
||||
|
||||
lfs_deinit();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1168,6 +1200,8 @@ int eq_load_name(uint8_t mode) {
|
||||
* @return 0: 成功, -1: 失败
|
||||
*/
|
||||
int eq_load_gain_and_names(void) {
|
||||
if (lfs_init() != 0) { lfs_deinit(); return -1; }
|
||||
|
||||
int ret = 0;
|
||||
|
||||
// 加载gain
|
||||
@@ -1183,6 +1217,7 @@ int eq_load_gain_and_names(void) {
|
||||
}
|
||||
|
||||
DPRINTF("Successfully loaded gain and mode names\n");
|
||||
lfs_deinit();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1204,10 +1239,13 @@ int eq_load_all_params_and_calculate_coefficients(uint32_t sample_rate, uint8_t
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lfs_init() != 0) { lfs_deinit(); return -1; }
|
||||
|
||||
// 获取EQ数组指针
|
||||
eq_mode_data_t (*eq_array)[NUM_EQ_MODES][NUM_EQ_CHANS] = get_eq_array_ptr(sample_rate);
|
||||
if (!eq_array) {
|
||||
DPRINTF(" Error: Failed to get EQ array for sample rate %u\n", sample_rate);
|
||||
lfs_deinit();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1224,6 +1262,7 @@ int eq_load_all_params_and_calculate_coefficients(uint32_t sample_rate, uint8_t
|
||||
//DPRINTF(" Loaded %d single parameters and calculated coefficients for mode %d\n",
|
||||
// loaded_count, mode);
|
||||
|
||||
lfs_deinit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1271,10 +1310,13 @@ int eq_flash_save_mode(uint8_t mode) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lfs_init() != 0) { lfs_deinit(); return -1; }
|
||||
|
||||
// 获取当前采样率的EQ数组指针
|
||||
eq_mode_data_t (*eq_array)[NUM_EQ_MODES][NUM_EQ_CHANS] = get_eq_array_ptr(g_eq_sample_rate);
|
||||
if (!eq_array) {
|
||||
DPRINTF(" Error: Failed to get EQ array for current sample rate %lu\n", (unsigned long)g_eq_sample_rate);
|
||||
lfs_deinit();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -1332,6 +1374,7 @@ int eq_flash_save_mode(uint8_t mode) {
|
||||
DPRINTF(" Successfully saved EQ parameters for mode %d, channel %d\n", mode, ch);
|
||||
}
|
||||
|
||||
lfs_deinit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1515,6 +1558,8 @@ int delete_flash_eq_params(uint8_t mode) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lfs_init() != 0) { lfs_deinit(); return -1; }
|
||||
|
||||
int deleted_count = 0;
|
||||
|
||||
if (mode == 0xFF) {
|
||||
@@ -1556,6 +1601,7 @@ int delete_flash_eq_params(uint8_t mode) {
|
||||
}
|
||||
|
||||
DPRINTF(" Deleted %d parameter files\n", deleted_count);
|
||||
lfs_deinit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1577,6 +1623,8 @@ int delete_flash_gain_and_names(uint8_t mode) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lfs_init() != 0) { lfs_deinit(); return -1; }
|
||||
|
||||
// 处理删除所有模式的情况
|
||||
if (mode == 0xFF) {
|
||||
DPRINTF(" Deleting all user mode gains and names\n");
|
||||
@@ -1604,18 +1652,21 @@ int delete_flash_gain_and_names(uint8_t mode) {
|
||||
}
|
||||
}
|
||||
|
||||
lfs_deinit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 检查模式有效性
|
||||
if (mode >= NUM_EQ_MODES) {
|
||||
DPRINTF(" Error: Invalid mode %d\n", mode);
|
||||
lfs_deinit();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 预设模式(0-5)的增益和名称不存储在Flash中,不需要删除
|
||||
if (mode < EQ_USER_MODE_MIN) {
|
||||
DPRINTF(" Mode %d is a preset mode, no Flash data to delete\n", mode);
|
||||
lfs_deinit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1674,11 +1725,13 @@ int delete_flash_gain_and_names(uint8_t mode) {
|
||||
DPRINTF(" Gains file does not exist: %s\n", file_path);
|
||||
}
|
||||
|
||||
lfs_deinit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 其他模式(如模式9)不需要处理
|
||||
DPRINTF(" Mode %d does not require Flash data deletion\n", mode);
|
||||
lfs_deinit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1775,6 +1828,8 @@ int eq_flash_save_eq_enable(uint8_t enable)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lfs_init() != 0) { lfs_deinit(); return -1; }
|
||||
|
||||
// 构建独立文件路径
|
||||
// 改动原因:使用独立的文件名存储eq_enable,与模式存储完全分离
|
||||
char file_path[FILE_PATH_MAX_LENGTH];
|
||||
@@ -1801,6 +1856,7 @@ int eq_flash_save_eq_enable(uint8_t enable)
|
||||
// 写入文件
|
||||
lfs_write_config(file_path, file_data, sizeof(file_data));
|
||||
DPRINTF(" Successfully saved EQ enable %d to Flash (independent file: %s)\n", enable, file_path);
|
||||
lfs_deinit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1826,6 +1882,8 @@ int eq_flash_save_current_mode(uint8_t mode)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lfs_init() != 0) { lfs_deinit(); return -1; }
|
||||
|
||||
// 构建独立文件路径
|
||||
// 改动原因:使用独立的文件名存储模式,与eq_enable存储完全分离
|
||||
char file_path[FILE_PATH_MAX_LENGTH];
|
||||
@@ -1852,6 +1910,7 @@ int eq_flash_save_current_mode(uint8_t mode)
|
||||
// 写入文件
|
||||
lfs_write_config(file_path, file_data, sizeof(file_data));
|
||||
DPRINTF(" Successfully saved EQ mode %d to Flash (independent file: %s)\n", mode, file_path);
|
||||
lfs_deinit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1872,6 +1931,8 @@ int eq_flash_load_current_mode(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lfs_init() != 0) { lfs_deinit(); return -1; }
|
||||
|
||||
// 加载模式(从独立文件)
|
||||
char mode_file_path[FILE_PATH_MAX_LENGTH];
|
||||
snprintf(mode_file_path, sizeof(mode_file_path), "%s", g_eq_flash_mode_file);
|
||||
@@ -1951,6 +2012,7 @@ int eq_flash_load_current_mode(void)
|
||||
g_eq_enable = eq_enable;
|
||||
|
||||
DPRINTF(" Successfully loaded mode %d and EQ enable %d from Flash (independent files)\n", mode, eq_enable);
|
||||
lfs_deinit();
|
||||
return mode;
|
||||
}
|
||||
|
||||
@@ -1970,6 +2032,8 @@ int eq_flash_load_eq_enable(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lfs_init() != 0) { lfs_deinit(); return -1; }
|
||||
|
||||
// 加载使能状态(从独立文件)
|
||||
char enable_file_path[FILE_PATH_MAX_LENGTH];
|
||||
snprintf(enable_file_path, sizeof(enable_file_path), "%s", g_eq_flash_enable_file);
|
||||
@@ -2012,5 +2076,6 @@ int eq_flash_load_eq_enable(void)
|
||||
g_eq_enable = eq_enable;
|
||||
|
||||
DPRINTF(" Successfully loaded EQ enable %d from Flash (independent file)\n", eq_enable);
|
||||
lfs_deinit();
|
||||
return eq_enable;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#if __XC__
|
||||
int lfs_init(void);
|
||||
void lfs_deinit(void);
|
||||
int lfs_format_all(void);
|
||||
void lfs_read_config(unsigned char * unsafe config, unsigned char * unsafe buffer, unsigned size);
|
||||
void lfs_write_config(unsigned char * unsafe config, unsigned char * unsafe buffer, unsigned size);
|
||||
// EQ参数专用函数
|
||||
@@ -15,6 +16,7 @@ int lfs_create_directory(const char * unsafe dir_path);
|
||||
|
||||
int lfs_init(void);
|
||||
void lfs_deinit(void);
|
||||
int lfs_format_all(void);
|
||||
void lfs_read_config(unsigned char * config, unsigned char * buffer, unsigned size);
|
||||
void lfs_write_config(unsigned char * config, unsigned char * buffer, unsigned size);
|
||||
// EQ参数专用函数
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
#if UART_DEBUG || DEBUG_MEMORY_LOG_ENABLED
|
||||
#define DEBUG_PRINT_ENABLE 1
|
||||
#else
|
||||
#define DEBUG_PRINT_ENABLE 0
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <xs1.h>
|
||||
#include <platform.h>
|
||||
@@ -68,8 +74,29 @@ const struct lfs_config cfg = {
|
||||
.block_cycles = 500,
|
||||
};
|
||||
|
||||
// Session-based exclusive flash access:
|
||||
// lfs_init() — acquire lock, init QSPI hardware, mount LFS. Lock is HELD.
|
||||
// lfs_deinit() — unmount LFS, release lock.
|
||||
// All flash I/O between init/deinit is protected. No per-operation locking needed.
|
||||
// Only ONE core can hold the session at a time. Other cores block in lfs_init().
|
||||
|
||||
#if HID_DFU_EN
|
||||
extern unsigned g_in_fw_upgrade;
|
||||
#endif
|
||||
|
||||
static int lfs_session_active = 0;
|
||||
|
||||
int lfs_init(void) {
|
||||
#if HID_DFU_EN
|
||||
// 固件升级期间禁止LFS操作,避免与DFU flash访问冲突
|
||||
if (g_in_fw_upgrade) {
|
||||
debug_printf("lfs_init: blocked during firmware upgrade\n");
|
||||
lfs_session_active = 0;
|
||||
return -2;
|
||||
}
|
||||
#endif
|
||||
swlock_acquire(&lfs_lock);
|
||||
lfs_session_active = 1;
|
||||
rtos_qspi_flash_init(
|
||||
qspi_flash_ctx,
|
||||
FLASH_CLKBLK,
|
||||
@@ -87,32 +114,61 @@ int lfs_init(void) {
|
||||
if (err) {
|
||||
debug_printf("no lfs partiton is found, formating ...\n");
|
||||
lfs_format(&lfs, &cfg);
|
||||
lfs_mount(&lfs, &cfg);
|
||||
swlock_release(&lfs_lock);
|
||||
return -1;
|
||||
err = lfs_mount(&lfs, &cfg);
|
||||
if (err) {
|
||||
debug_printf("lfs_init: format+remount failed, err=%d\n", err);
|
||||
lfs_session_active = 0;
|
||||
swlock_release(&lfs_lock);
|
||||
return -1;
|
||||
}
|
||||
// Format succeeded and FS is now mounted — return 0 so callers
|
||||
// can proceed with reads/writes on the (now empty) filesystem.
|
||||
debug_printf("lfs_init: formatted and remounted successfully\n");
|
||||
return 0;
|
||||
}
|
||||
swlock_release(&lfs_lock);
|
||||
// Lock remains held until lfs_deinit() is called
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void lfs_deinit(void) {
|
||||
swlock_acquire(&lfs_lock);
|
||||
if (!lfs_session_active) {
|
||||
return; // lfs_init was blocked (e.g. during firmware upgrade), nothing to clean up
|
||||
}
|
||||
lfs_unmount(&lfs);
|
||||
lfs_session_active = 0;
|
||||
swlock_release(&lfs_lock);
|
||||
}
|
||||
|
||||
int lfs_format_all(void) {
|
||||
int res = lfs_init();
|
||||
if (res != 0) {
|
||||
return res; // Already failed and released lock, or blocked
|
||||
}
|
||||
|
||||
// Mount succeeded, but we want to format, so unmount first
|
||||
lfs_unmount(&lfs);
|
||||
|
||||
// 格式化整个LFS分区,清除所有数据
|
||||
int err = lfs_format(&lfs, &cfg);
|
||||
|
||||
// Even if format fails, we must cleanup the session
|
||||
lfs_session_active = 0;
|
||||
swlock_release(&lfs_lock);
|
||||
return err;
|
||||
}
|
||||
|
||||
// All functions below must be called within an lfs_init()/lfs_deinit() session.
|
||||
// No internal locking — the session lock protects the entire operation sequence.
|
||||
|
||||
#pragma stackfunction 1500
|
||||
void lfs_read_config(unsigned char * config, unsigned char * buffer, unsigned size)
|
||||
{
|
||||
swlock_acquire(&lfs_lock);
|
||||
debug_printf("lfs_read_config: %s, size: %d\n", config, size);
|
||||
int result = lfs_file_open(&lfs, &file, config, LFS_O_RDWR | LFS_O_CREAT);
|
||||
debug_printf("lfs_read_config: %s, result: %d\n", config, result);
|
||||
if (result != 0) {
|
||||
debug_printf("lfs_read_config: %s, open file failed\n", config);
|
||||
swlock_release(&lfs_lock);
|
||||
return;
|
||||
}
|
||||
debug_printf("lfs_read_config: %s, file opened\n", config);
|
||||
@@ -120,39 +176,30 @@ void lfs_read_config(unsigned char * config, unsigned char * buffer, unsigned si
|
||||
debug_printf("lfs_read_config: %s, result: %d\n", config, result);
|
||||
if (result < 0) {
|
||||
debug_printf("lfs_read_config: %s, read file failed, error: %d\n", config, result);
|
||||
// Update: Added lfs_file_close to ensure file is closed even on error.
|
||||
// Missing this caused subsequent open calls to assert/crash.
|
||||
lfs_file_close(&lfs, &file);
|
||||
swlock_release(&lfs_lock);
|
||||
return;
|
||||
}
|
||||
lfs_file_close(&lfs, &file);
|
||||
swlock_release(&lfs_lock);
|
||||
}
|
||||
|
||||
|
||||
#pragma stackfunction 1500
|
||||
void lfs_write_config(unsigned char * config, unsigned char * buffer, unsigned size)
|
||||
{
|
||||
swlock_acquire(&lfs_lock);
|
||||
debug_printf("lfs_write_config: %s, size: %d\n", config, size);
|
||||
int result = lfs_file_open(&lfs, &file, config, LFS_O_RDWR | LFS_O_CREAT);
|
||||
if (result != 0) {
|
||||
debug_printf("lfs_write_config: open file failed\n");
|
||||
swlock_release(&lfs_lock);
|
||||
return;
|
||||
}
|
||||
result = lfs_file_rewind(&lfs, &file);
|
||||
if (result != 0) {
|
||||
debug_printf("lfs_write_config: rewind file failed\n");
|
||||
// Update: Added lfs_file_close to prevent file remaining open if rewind fails.
|
||||
lfs_file_close(&lfs, &file);
|
||||
swlock_release(&lfs_lock);
|
||||
return;
|
||||
}
|
||||
lfs_file_write(&lfs, &file, buffer, size);
|
||||
lfs_file_close(&lfs, &file);
|
||||
swlock_release(&lfs_lock);
|
||||
}
|
||||
|
||||
|
||||
@@ -160,15 +207,12 @@ void lfs_write_config(unsigned char * config, unsigned char * buffer, unsigned s
|
||||
#pragma stackfunction 1200
|
||||
int lfs_file_exists(const char * file_path)
|
||||
{
|
||||
swlock_acquire(&lfs_lock);
|
||||
lfs_file_t file;
|
||||
int result = lfs_file_open(&lfs, &file, file_path, LFS_O_RDONLY);
|
||||
if (result == 0) {
|
||||
lfs_file_close(&lfs, &file);
|
||||
swlock_release(&lfs_lock);
|
||||
return 1; // 文件存在
|
||||
}
|
||||
swlock_release(&lfs_lock);
|
||||
return 0; // 文件不存在
|
||||
}
|
||||
|
||||
|
||||
@@ -83,6 +83,7 @@ void save_value(unsigned char *path, unsigned char value)
|
||||
//uint32_t t = get_reference_time();
|
||||
if (lfs_init() == 0)
|
||||
{
|
||||
debug_printf("save value %02x to %s\n", value, path);
|
||||
lfs_write_config(path, (unsigned char*) &value, sizeof(value));
|
||||
}
|
||||
|
||||
@@ -95,6 +96,7 @@ unsigned char load_value(unsigned char *path)
|
||||
if (lfs_init() == 0)
|
||||
{
|
||||
lfs_read_config(path, (unsigned char*) &value, sizeof(value));
|
||||
debug_printf("load value from %s %02x\n", path, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user