修复IWDG超时未配置与dhara resume回滚:看门狗误复位与复位后写入全部丢失,台架全量自检PASS
This commit is contained in:
@@ -7,6 +7,8 @@
|
||||
|
||||
#include "ff.h"
|
||||
#include "private/lftpd_io.h"
|
||||
#include "lftpd.h"
|
||||
#include "vol_lock.h"
|
||||
|
||||
#define DBG_TAG "[LFT_IO]"
|
||||
#include "dbg_log.h"
|
||||
@@ -32,6 +34,24 @@ static const char *to_fatfs_path(const char *path)
|
||||
static int s_file_open = 0;
|
||||
static FIL s_ftp_file;
|
||||
|
||||
/*
|
||||
* 卷锁获取(分片阻塞 + 心跳):FatFs/FTL 卷状态非线程安全,文件操作序列
|
||||
* 必须与 defaultTask 的 syslog/配置盘写互斥(2026-10-02 台架实证:并发
|
||||
* FTL 写 → dhara journal 竞争 → 长耗时恢复旋转饥饿 defaultTask 主循环
|
||||
* (看门狗喂狗点)→ IWDG 误复位)。等待按 100ms 分片、每片置 FTP 心跳位
|
||||
* (与就绪屏障等待同模式),防长等待造成 FTP 心跳位缺席误复位。
|
||||
* 持有约定:open...close / opendir...closedir 全程持锁;lftpd_io_read/
|
||||
* write 假定锁已由 open 持有;stat/unlink 自行短持。
|
||||
*/
|
||||
static void lftpd_io_vol_lock_take(void) {
|
||||
for (;;) {
|
||||
if (vol_lock_wait(100u) != 0) {
|
||||
return;
|
||||
}
|
||||
lftpd_task_wd_beat(); /* 看门狗:分片心跳(卷锁等待中) */
|
||||
}
|
||||
}
|
||||
|
||||
char *lftpd_io_canonicalize_path(const char *base, const char *name)
|
||||
{
|
||||
if (base == NULL) {
|
||||
@@ -100,10 +120,12 @@ int lftpd_io_open_read(const char *path)
|
||||
DBG_ERROR("open_read '%s': already open", path);
|
||||
return -1;
|
||||
}
|
||||
lftpd_io_vol_lock_take();
|
||||
const char *fpath = to_fatfs_path(path);
|
||||
FRESULT fr = f_open(&s_ftp_file, fpath, FA_READ);
|
||||
if (fr != FR_OK) {
|
||||
DBG_ERROR("open_read '%s': f_open err=%d", fpath, (int)fr);
|
||||
vol_lock_release();
|
||||
return -1;
|
||||
}
|
||||
s_file_open = 1;
|
||||
@@ -116,10 +138,12 @@ int lftpd_io_open_write(const char *path)
|
||||
DBG_ERROR("open_write '%s': already open", path);
|
||||
return -1;
|
||||
}
|
||||
lftpd_io_vol_lock_take();
|
||||
const char *fpath = to_fatfs_path(path);
|
||||
FRESULT fr = f_open(&s_ftp_file, fpath, FA_WRITE | FA_CREATE_ALWAYS);
|
||||
if (fr != FR_OK) {
|
||||
DBG_ERROR("open_write '%s': f_open err=%d", fpath, (int)fr);
|
||||
vol_lock_release();
|
||||
return -1;
|
||||
}
|
||||
s_file_open = 1;
|
||||
@@ -155,6 +179,7 @@ void lftpd_io_close(int handle)
|
||||
if (s_file_open) {
|
||||
f_close(&s_ftp_file);
|
||||
s_file_open = 0;
|
||||
vol_lock_release(); /* 卷锁:open...close 序列结束 */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,7 +188,9 @@ int lftpd_io_stat(const char *path, uint32_t *p_size, int *p_is_dir)
|
||||
FILINFO fno;
|
||||
const char *fpath = to_fatfs_path(path);
|
||||
|
||||
lftpd_io_vol_lock_take();
|
||||
if (f_stat(fpath, &fno) != FR_OK) {
|
||||
vol_lock_release();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -174,15 +201,19 @@ int lftpd_io_stat(const char *path, uint32_t *p_size, int *p_is_dir)
|
||||
*p_is_dir = (fno.fattrib & AM_DIR) ? 1 : 0;
|
||||
}
|
||||
|
||||
vol_lock_release();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lftpd_io_unlink(const char *path)
|
||||
{
|
||||
const char *fpath = to_fatfs_path(path);
|
||||
lftpd_io_vol_lock_take();
|
||||
if (f_unlink(fpath) == FR_OK) {
|
||||
vol_lock_release();
|
||||
return 0;
|
||||
}
|
||||
vol_lock_release();
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -193,11 +224,13 @@ void *lftpd_io_opendir(const char *path)
|
||||
return NULL;
|
||||
}
|
||||
const char *fpath = to_fatfs_path(path);
|
||||
lftpd_io_vol_lock_take();
|
||||
if (f_opendir(dp, fpath) != FR_OK) {
|
||||
vPortFree(dp);
|
||||
vol_lock_release();
|
||||
return NULL;
|
||||
}
|
||||
return (void *)dp;
|
||||
return (void *)dp; /* 卷锁持有至 lftpd_io_closedir */
|
||||
}
|
||||
|
||||
int lftpd_io_readdir(void *dp, char *name, int name_max, uint32_t *p_size, int *p_is_dir)
|
||||
@@ -233,5 +266,6 @@ void lftpd_io_closedir(void *dp)
|
||||
if (dp != NULL) {
|
||||
f_closedir((DIR *)dp);
|
||||
vPortFree(dp);
|
||||
vol_lock_release(); /* 卷锁:opendir...closedir 序列结束 */
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user