From 0669471178dda7e4a83c0e7d5fbd0440e974ec9f Mon Sep 17 00:00:00 2001 From: Wanderingss <1624155937@qq.com> Date: Sun, 20 Sep 2026 05:12:08 +0800 Subject: [PATCH] =?UTF-8?q?FTL=E8=AF=8A=E6=96=AD=EF=BC=9AL0=E6=8E=A2?= =?UTF-8?q?=E9=92=88=E7=AA=97=E5=8F=A3=E7=BB=91=E5=AE=9A=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E6=97=A5=E5=BF=97=EF=BC=88FAT=E8=AF=BBLPN=E2=86=92=E7=89=A9?= =?UTF-8?q?=E7=90=86=E9=A1=B5+=E5=86=99=E7=9B=AE=E6=A0=87=EF=BC=89+?= =?UTF-8?q?=E9=87=8D=E6=A0=BC=E5=BC=8F=E5=8C=96=E8=A1=8C=E5=B8=A6fr?= =?UTF-8?q?=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Drivers/BSP/GD5F2GQ5UE/nand_ftl.c | 35 ++++++++++++++++++++++++++----- Drivers/BSP/GD5F2GQ5UE/nand_ftl.h | 1 + Src/freertos.c | 7 ++++++- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/Drivers/BSP/GD5F2GQ5UE/nand_ftl.c b/Drivers/BSP/GD5F2GQ5UE/nand_ftl.c index b65e6670..e89a37fd 100644 --- a/Drivers/BSP/GD5F2GQ5UE/nand_ftl.c +++ b/Drivers/BSP/GD5F2GQ5UE/nand_ftl.c @@ -54,6 +54,20 @@ static uint8_t s_initialized; /* resume 搜索探针日志窗口(诊断:逐探测记录判定输入) */ static uint8_t s_probe_log; +/* L0 卷健康探针窗口(诊断:记录 FAT 读的 LPN 绑定 → 物理页路径) */ +static uint8_t s_tree_probe_log; + +/* + * 函数功能:打开/关闭 L0 卷健康探针日志窗口 + * 入口参数:on - 1 打开,0 关闭 + * 返回值:无 + * 限定条件:FTL 已初始化 + * 函数说明:窗口内的 dhara_nand_read/is_free/is_bad 调用逐条记录 + * 物理页(= journal LPN),用于判定 map 绑定指向 + */ +void nand_ftl_set_tree_probe(uint8_t on) { + s_tree_probe_log = on; +} /* ======================== 私有函数声明 ======================== */ @@ -90,6 +104,10 @@ static int ftl_read_page(dhara_sector_t lpn) { s_cached_lpn = lpn; s_cache_dirty = 0; + if (s_tree_probe_log) { + DBG_INFO("ftl read LPN=%lu (binding see nand read lines)", + (unsigned long)lpn); + } return GD5F_OK; } @@ -98,7 +116,7 @@ static int ftl_read_page(dhara_sector_t lpn) { int dhara_nand_is_bad(const struct dhara_nand *n, dhara_block_t b) { (void)n; const int bad = gd5f2gq5ue_is_block_bad(ftl_phy_block(b)); - if (s_probe_log) { + if (s_probe_log || s_tree_probe_log) { DBG_INFO("probe blk %lu: bbt_bad=%u", (unsigned long)b, (unsigned int)bad); } @@ -125,6 +143,12 @@ int dhara_nand_prog(const struct dhara_nand *n, dhara_page_t p, const uint8_t *d int ret; uint32_t phy_pg = ftl_phy_page(p); + if (s_probe_log || s_tree_probe_log) { + DBG_INFO("probe t %lu prog pg %lu blk %lu g%lu", + (unsigned long)HAL_GetTick(), (unsigned long)phy_pg, + (unsigned long)(p >> 6), (unsigned long)((p >> 4) & 3u)); + } + gd5f_write_enable(); ret = gd5f_program_load(0, data, FTL_PAGE_SIZE); if (ret != GD5F_OK) { @@ -193,7 +217,7 @@ int dhara_nand_is_free(const struct dhara_nand *n, dhara_page_t p) { } } } - if (s_probe_log) { + if (s_probe_log || s_tree_probe_log) { DBG_INFO("probe t %lu isfree pg %lu = %u", (unsigned long)HAL_GetTick(), (unsigned long)phy_pg, (unsigned int)fre); @@ -208,7 +232,7 @@ int dhara_nand_read(const struct dhara_nand *n, dhara_page_t p, size_t offset, s int eret; if ((rret = gd5f_page_read(phy_pg)) != GD5F_OK) { - if (s_probe_log) { + if (s_probe_log || s_tree_probe_log) { DBG_INFO("probe pg %lu blk %lu: page_read=%d", (unsigned long)phy_pg, (unsigned long)(p >> 6), rret); @@ -218,7 +242,7 @@ int dhara_nand_read(const struct dhara_nand *n, dhara_page_t p, size_t offset, s } if ((eret = gd5f_check_ecc()) != GD5F_OK) { - if (s_probe_log) { + if (s_probe_log || s_tree_probe_log) { DBG_INFO("probe pg %lu blk %lu: ecc=%d", (unsigned long)phy_pg, (unsigned long)(p >> 6), eret); @@ -229,7 +253,8 @@ int dhara_nand_read(const struct dhara_nand *n, dhara_page_t p, size_t offset, s gd5f_read_from_cache((uint16_t)offset, data, length); - if (s_probe_log && offset == 0 && length == FTL_PAGE_SIZE) { + if ((s_probe_log || s_tree_probe_log) && + offset == 0 && length == FTL_PAGE_SIZE) { /* 组末页(组内偏移 15:页号低 4 位 = 15)= checkpoint 页: * 记录 header 前 4 字节 + meta 区 4 字节(偏移 944 = 槽 7, * 树根 meta)+ 时间戳。header 新/meta 旧 = 半新半旧混合页 diff --git a/Drivers/BSP/GD5F2GQ5UE/nand_ftl.h b/Drivers/BSP/GD5F2GQ5UE/nand_ftl.h index a216e7ec..e67d6848 100644 --- a/Drivers/BSP/GD5F2GQ5UE/nand_ftl.h +++ b/Drivers/BSP/GD5F2GQ5UE/nand_ftl.h @@ -14,6 +14,7 @@ void nand_ftl_deinit(void); /* 诊断接口:打印 journal 状态 / 全扫 checkpoint 分布(跨复位持久性分析) */ void nand_ftl_log_state(const char *tag); void nand_ftl_scan_checks(void); +void nand_ftl_set_tree_probe(uint8_t on); #ifdef __cplusplus } diff --git a/Src/freertos.c b/Src/freertos.c index 0735220c..f918c2fb 100644 --- a/Src/freertos.c +++ b/Src/freertos.c @@ -260,9 +260,13 @@ void StartDefaultTask(void *argument) } \ } while (0) FRESULT hfr; + nand_ftl_set_tree_probe(1); FS_VOL_PROBE(hfr); if (hfr != FR_OK) { FS_VOL_PROBE(hfr); /* 两击确认 */ + } + nand_ftl_set_tree_probe(0); + if (hfr != FR_OK) { nand_ftl_scan_checks(); /* 诊断:环上 checkpoint 的 epoch 分布 */ } if (hfr != FR_OK) { @@ -270,7 +274,8 @@ void StartDefaultTask(void *argument) hfr == FR_INT_ERR || hfr == FR_DISK_ERR || hfr == FR_NO_FILE || hfr == FR_NO_PATH || hfr == FR_INVALID_NAME || hfr == FR_NO_FILESYSTEM) { - DBG_INFO("[FS] volume FAT invalid, reformatting..."); + DBG_INFO("[FS] volume FAT invalid (fr=%d), reformatting...", + (int)hfr); f_mount(NULL, "", 0); { static uint8_t fs_work2[FF_MAX_SS];