update flash_lock

This commit is contained in:
Steven Dan
2026-05-19 15:57:22 +08:00
parent 33798ac42a
commit 69715f51d9
4 changed files with 126 additions and 43 deletions

View File

@@ -9,6 +9,10 @@
#include <string.h>
#include <stdio.h>
#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; // 状态码:成功

View File

@@ -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的模式编号

View File

@@ -1,5 +1,5 @@
#include <stdlib.h>
#include "xs1.h"
#include <xs1.h>
#include <platform.h>
#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];

View File

@@ -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);
}
}