FTL诊断:L0探针窗口绑定路径日志(FAT读LPN→物理页+写目标)+重格式化行带fr码

This commit is contained in:
2026-09-20 05:12:08 +08:00
parent 7bfa312b56
commit 0669471178
3 changed files with 37 additions and 6 deletions
+30 -5
View File
@@ -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 旧 = 半新半旧混合页
+1
View File
@@ -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
}
+6 -1
View File
@@ -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];