diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_lp/src/extensions/dfu_upgrade.c b/sw_usb_audio/app_usb_aud_fosi_c1_lp/src/extensions/dfu_upgrade.c index 5de77a6..127cb8e 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1_lp/src/extensions/dfu_upgrade.c +++ b/sw_usb_audio/app_usb_aud_fosi_c1_lp/src/extensions/dfu_upgrade.c @@ -9,6 +9,10 @@ #include #include #include "debug_print.h" +#include "swlock.h" + +// Global flash lock defined in lfs_services.c — protects all flash hardware access +extern swlock_t flash_lock; #if HID_DFU_EN // 外部函数声明 @@ -178,11 +182,14 @@ unsigned char handle_firmware_upgrade_start(uint8_t data[], uint16_t len) // 页对齐处理(向上取整到256字节) uint32_t aligned_size = ((firmware_size + FLASH_PAGE_SIZE - 1) / FLASH_PAGE_SIZE) * FLASH_PAGE_SIZE; - - // 初始化Flash接口(参考DFU_OpenFlash实现) + + // Acquire global flash lock — held until END or ABORT releases it + swlock_acquire(&flash_lock); + if (dfu_flash_cmd_init() != 0) { debug_printf("Firmware upgrade error: flash init failed\n"); - response[0] = STATUS_FAIL; // 状态码:失败 + swlock_release(&flash_lock); + response[0] = STATUS_FAIL; send_firmware_upgrade_response(FIRMWARE_UPGRADE_START, response, 1); return STATUS_FAIL; } @@ -226,7 +233,8 @@ unsigned char handle_firmware_upgrade_start(uint8_t data[], uint16_t len) debug_printf("Firmware upgrade error: first page write command failed (begin_write error)\n"); dfu_flash_cmd_deinit(); g_upgrade_status.state = UPGRADE_IDLE; - response[0] = STATUS_FAIL; // 状态码:失败 + swlock_release(&flash_lock); + response[0] = STATUS_FAIL; send_firmware_upgrade_response(FIRMWARE_UPGRADE_START, response, 1); return STATUS_FAIL; } @@ -442,7 +450,8 @@ unsigned char handle_firmware_upgrade_end(uint8_t data[], uint16_t len) debug_printf("Firmware upgrade error: flash write termination failed\n"); g_upgrade_status.state = UPGRADE_ERROR; g_upgrade_status.error_code = STATUS_FAIL; - response[0] = STATUS_FAIL; // 状态码:失败 + swlock_release(&flash_lock); + response[0] = STATUS_FAIL; send_firmware_upgrade_response(FIRMWARE_UPGRADE_END, response, 1); return STATUS_FAIL; } @@ -463,6 +472,7 @@ unsigned char handle_firmware_upgrade_end(uint8_t data[], uint16_t len) /* 改动原因:通知 MCU 固件升级已正常结束 */ g_firmware_upgrade_mcu_notify = 2; g_in_fw_upgrade = 0; + swlock_release(&flash_lock); g_upgrade_status.state = UPGRADE_IDLE; return STATUS_SUCCESS; } @@ -538,7 +548,7 @@ unsigned char handle_firmware_upgrade_abort(uint8_t data[], uint16_t len) /* 改动原因:通知 MCU 固件升级已中止/失败 */ g_firmware_upgrade_mcu_notify = 3; g_in_fw_upgrade = 0; - // 重置为IDLE状态 + swlock_release(&flash_lock); g_upgrade_status.state = UPGRADE_IDLE; return STATUS_SUCCESS; } @@ -551,10 +561,11 @@ unsigned char handle_firmware_upgrade_erase(uint8_t data[], uint16_t len) debug_printf("Firmware upgrade ERASE: erasing all upgrade images\n"); - // 初始化Flash接口 + swlock_acquire(&flash_lock); if (dfu_flash_cmd_init() != 0) { debug_printf("Firmware upgrade error: flash init failed\n"); - response[0] = STATUS_FAIL; // 状态码:失败 + swlock_release(&flash_lock); + response[0] = STATUS_FAIL; send_firmware_upgrade_response(FIRMWARE_UPGRADE_ERASE, response, 1); return STATUS_FAIL; } @@ -568,6 +579,7 @@ unsigned char handle_firmware_upgrade_erase(uint8_t data[], uint16_t len) } dfu_flash_cmd_deinit(); + swlock_release(&flash_lock); // 构建响应数据包 response[0] = STATUS_SUCCESS; // 状态码:成功 diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_lp/src/extensions/eq.c b/sw_usb_audio/app_usb_aud_fosi_c1_lp/src/extensions/eq.c index c64344f..33f3209 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1_lp/src/extensions/eq.c +++ b/sw_usb_audio/app_usb_aud_fosi_c1_lp/src/extensions/eq.c @@ -19,7 +19,12 @@ void device_reboot(void); extern void SetRoleSwitchFlag(unsigned mode); extern unsigned g_3d_fps; +#if DEBUG_MEMORY_LOG_ENABLED unsigned g_log_switch = 1; +#else +unsigned g_log_switch = 0; +#endif + // 常量定义 #define EQ_DISABLED_MODE 10 // 禁用EQ的模式编号 diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_lp/src/extensions/lfs_services.c b/sw_usb_audio/app_usb_aud_fosi_c1_lp/src/extensions/lfs_services.c index d4d53f9..139b0a8 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1_lp/src/extensions/lfs_services.c +++ b/sw_usb_audio/app_usb_aud_fosi_c1_lp/src/extensions/lfs_services.c @@ -1,5 +1,5 @@ #include -#include "xs1.h" +#include #include #include "lfs.h" #include "rtos_qspi_flash.h" @@ -12,17 +12,20 @@ // variables used by the filesystem lfs_t lfs; lfs_file_t file; -swlock_t lfs_lock = SWLOCK_INITIAL_VALUE; + +// Global flash lock: protects ALL flash hardware access (LFS, DFU, key programming). +// Only one core may perform flash I/O at a time. +swlock_t flash_lock = SWLOCK_INITIAL_VALUE; static rtos_qspi_flash_t qspi_flash_ctx_s; -#define FLASH_CLKBLK CLKBLK_FLASHLIB +#define FLASH_CLKBLK CLKBLK_FLASHLIB #ifndef FS_BASE_ADDR #define FS_BASE_ADDR (3500 * 1024) #endif #define SECTOR_SIZE 4096 rtos_qspi_flash_t *qspi_flash_ctx = &qspi_flash_ctx_s; -__attribute__((fptrgroup(" local_block_device_read_fptr_grp"))) +__attribute__((fptrgroup("local_block_device_read_fptr_grp"))) int local_block_device_read(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size) { @@ -31,7 +34,7 @@ int local_block_device_read(const struct lfs_config *c, lfs_block_t block, return 0; } -__attribute__((fptrgroup(" local_block_device_prog_fptr_grp"))) +__attribute__((fptrgroup("local_block_device_prog_fptr_grp"))) int local_block_device_prog(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size) { @@ -40,7 +43,7 @@ int local_block_device_prog(const struct lfs_config *c, lfs_block_t block, return 0; } -__attribute__((fptrgroup(" local_block_device_erase_fptr_grp"))) +__attribute__((fptrgroup("local_block_device_erase_fptr_grp"))) int local_block_device_erase(const struct lfs_config *c, lfs_block_t block) { unsigned address = (FS_BASE_ADDR + block * SECTOR_SIZE); @@ -48,7 +51,7 @@ int local_block_device_erase(const struct lfs_config *c, lfs_block_t block) return 0; } -__attribute__((fptrgroup(" local_block_device_sync_fptr_grp"))) +__attribute__((fptrgroup("local_block_device_sync_fptr_grp"))) int local_block_device_sync(const struct lfs_config *c) { return 0; @@ -72,14 +75,35 @@ 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) { - swlock_acquire(&lfs_lock); +#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(&flash_lock); + lfs_session_active = 1; rtos_qspi_flash_init( qspi_flash_ctx, FLASH_CLKBLK, - PORT_SQI_CS, - PORT_SQI_SCLK, - PORT_SQI_SIO, + XS1_PORT_1B, + XS1_PORT_1C, + XS1_PORT_4B, NULL); @@ -91,22 +115,53 @@ 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(&flash_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); - swlock_release(&lfs_lock); + lfs_session_active = 0; + swlock_release(&flash_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(&flash_lock); + return err; } -#pragma stackfunction 1480 +// 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) { // 改动原因:升级过程中禁止Flash读操作 @@ -116,13 +171,12 @@ void lfs_read_config(unsigned char * config, unsigned char * buffer, unsigned si return; } #endif - 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); @@ -130,17 +184,14 @@ 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 1480 + +#pragma stackfunction 1500 void lfs_write_config(unsigned char * config, unsigned char * buffer, unsigned size) { // 改动原因:升级过程中禁止Flash写操作 @@ -150,44 +201,39 @@ void lfs_write_config(unsigned char * config, unsigned char * buffer, unsigned s return; } #endif - 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); } // 检查文件是否存在 +#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; // 文件不存在 } // EQ参数专用读写函数 +#pragma stackfunction 1200 void lfs_read_eq_config(const char * file_path, unsigned char * buffer, unsigned size) { lfs_file_open(&lfs, &file, file_path, LFS_O_RDONLY); @@ -195,6 +241,7 @@ void lfs_read_eq_config(const char * file_path, unsigned char * buffer, unsigned lfs_file_close(&lfs, &file); } +#pragma stackfunction 1500 void lfs_write_eq_config(const char * file_path, unsigned char * buffer, unsigned size) { lfs_file_open(&lfs, &file, file_path, LFS_O_RDWR | LFS_O_CREAT); @@ -205,12 +252,14 @@ void lfs_write_eq_config(const char * file_path, unsigned char * buffer, unsigne // 删除文件 +#pragma stackfunction 1500 int lfs_remove_file(const char * file_path) { return lfs_remove(&lfs, file_path); } // 创建目录(通过创建临时文件然后删除) +#pragma stackfunction 1500 int lfs_create_directory(const char * dir_path) { char temp_file[256]; diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_lp/src/extensions/program_key.c b/sw_usb_audio/app_usb_aud_fosi_c1_lp/src/extensions/program_key.c index 1f51f9c..065e6b2 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1_lp/src/extensions/program_key.c +++ b/sw_usb_audio/app_usb_aud_fosi_c1_lp/src/extensions/program_key.c @@ -10,7 +10,10 @@ #include "uac_hwresources.h" #include "hmac.h" #include "xua_conf.h" +#include "swlock.h" +// Global flash lock defined in lfs_services.c — protects all flash hardware access +extern swlock_t flash_lock; #define WRITE_ENABLE_COMMAND (0x06) #define WRITE_DISABLE_COMMAND (0x04) @@ -161,10 +164,13 @@ void flash_opt_unlock(void) uint8_t data[1] = {0}; uint8_t sr1, sr2, sr3; uint8_t did[3]; - + + swlock_acquire(&flash_lock); + /* Reason: 使用 tile0 端口连接 Flash,保持原有逻辑 */ if (flash_opt_enable_ports(&p_qflash_tile0) == 0) { debug_printf("flash_opt_unlock failed\n"); + swlock_release(&flash_lock); return; } @@ -222,6 +228,7 @@ void flash_opt_unlock(void) } flash_opt_disable_ports(); + swlock_release(&flash_lock); debug_printf("Unlock Winbond Flash done\n"); } @@ -302,9 +309,10 @@ uint8_t opt_key_read(uint8_t key[], unsigned offset) { uint8_t read_bin[KEY_BLOCK_LEN + 1]; uint8_t ret = 0; - + swlock_acquire(&flash_lock); if (flash_opt_enable_ports(&p_qflash_tile0) == 0) { + swlock_release(&flash_lock); return 0; } @@ -314,6 +322,7 @@ uint8_t opt_key_read(uint8_t key[], unsigned offset) key[i] = read_bin[i + offset * 20 + 1]; } flash_opt_disable_ports(); + swlock_release(&flash_lock); return 1; } @@ -406,8 +415,10 @@ uint8_t key_validate(uint8_t offset) uint8_t did[4]; uint8_t hmac_bin[20]; + swlock_acquire(&flash_lock); if (flash_opt_enable_ports(&p_qflash_tile0) == 0) { + swlock_release(&flash_lock); return 0; } @@ -424,19 +435,23 @@ uint8_t key_validate(uint8_t offset) } flash_opt_disable_ports(); + swlock_release(&flash_lock); return ret; } void read_uid_did(uint8_t uid[]) { + swlock_acquire(&flash_lock); if (flash_opt_enable_ports(&p_qflash_tile0) == 0) { + swlock_release(&flash_lock); return; } flash_opt_read_uid(uid, 20); flash_opt_read_did(uid, 3); flash_opt_disable_ports(); + swlock_release(&flash_lock); } @@ -445,6 +460,7 @@ void program_key(uint8_t *buffer, int datalength) if (buffer[0] == 0x77 && buffer[1] == 0x5B) { uint8_t ret = 0; + swlock_acquire(&flash_lock); switch (buffer[2]) { case 1: @@ -652,5 +668,6 @@ void program_key(uint8_t *buffer, int datalength) case 11: break; } + swlock_release(&flash_lock); } }