update flash_lock
This commit is contained in:
@@ -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; // 状态码:成功
|
||||
|
||||
@@ -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的模式编号
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user