CCM扩容FreeRTOS堆+DMA阈值1024防栈缓冲进CCM+HardFault现场报告与栈/内存钩子+修defaultTask栈溢出+LVGL绘制缓冲护栏+存储套件05/06与恢复模式
This commit is contained in:
+1
-1
@@ -48,7 +48,7 @@ void storage_test_run(void);
|
||||
/* 存储套件恢复测试(默认关闭):取消注释并编译 STORAGE 套件运行一次,
|
||||
* 即可重建 BBT(清除 TC-STO-03 等注入的坏块)并重新格式化,恢复设备干净态。
|
||||
* 恢复完成后建议重新注释并编译正常构建。 */
|
||||
//#define ENABLE_STORAGE_RECOVERY_TESTS
|
||||
//#define ENABLE_STORAGE_RECOVERY_TESTS /* 台架已跑过一次恢复(2026-09-20 BBT 回出厂态),保持注释 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+174
-14
@@ -19,15 +19,22 @@
|
||||
|
||||
storage_test_stats_t g_storage_stats;
|
||||
|
||||
static uint8_t s_perf_buf[4096];
|
||||
#ifndef ENABLE_STORAGE_RECOVERY_TESTS
|
||||
/* 全套件共享的 FATFS/FIL(RAM 预算紧张:每个 static FATFS≈560B、FIL≈600B,
|
||||
* 各测试函数独立持有会撑爆 .bss。测试在单任务 testTask 内串行执行、从不并发,
|
||||
* 共用一组安全,且比"每函数一份"省下约 5KB。见产品级 RAM 溢出 L6406E) */
|
||||
static FATFS fs;
|
||||
static FIL fil;
|
||||
|
||||
/* 性能缓冲 2048B = 恰好一个 NAND 页(RAM 预算:4096 时套件链接溢出 0x604,
|
||||
* L6406E 实测;2048 分块仍覆盖整页写路径,128KB 总量不变) */
|
||||
static uint8_t s_perf_buf[2048];
|
||||
|
||||
/* TC-STO-01: FTL 掉电恢复(journal 持久化)
|
||||
* 写文件并同步落盘,随后模拟掉电(卸载 + 复位 FTL + 重新 resume),再挂载校验内容一致。
|
||||
*/
|
||||
static void storage_test_powerloss(void)
|
||||
{
|
||||
static FATFS fs;
|
||||
static FIL fil;
|
||||
const uint32_t len = 4096;
|
||||
uint8_t wbuf[512];
|
||||
uint8_t rbuf[512];
|
||||
@@ -90,14 +97,14 @@ static void storage_test_powerloss(void)
|
||||
|
||||
/* TC-STO-02: 大文件 / 多扇区 / 随机 seek
|
||||
* 写 256KB 位置相关模式文件,顺序读回比对 + 随机偏移 seek 读比对。
|
||||
* 栈预算:testTask 栈 4KB,局部缓冲 4096 必然溢出栈(8 月侥幸未爆是堆使用
|
||||
* 低),改 2048 = 恰好一个 NAND 整页,覆盖度等价。
|
||||
*/
|
||||
static void storage_test_largefile(void)
|
||||
{
|
||||
static FATFS fs;
|
||||
static FIL fil;
|
||||
const uint32_t total = 256 * 1024;
|
||||
const uint32_t chunk = 4096;
|
||||
uint8_t buf[4096];
|
||||
const uint32_t chunk = 2048;
|
||||
uint8_t buf[2048];
|
||||
UINT bw, br;
|
||||
uint32_t off, i;
|
||||
int ok = 1;
|
||||
@@ -162,8 +169,6 @@ static void storage_test_largefile(void)
|
||||
*/
|
||||
static void storage_test_badblock(void)
|
||||
{
|
||||
static FATFS fs;
|
||||
static FIL fil;
|
||||
uint8_t wbuf[512], rbuf[512];
|
||||
UINT bw, br;
|
||||
uint32_t bad[3];
|
||||
@@ -242,17 +247,150 @@ static void storage_test_badblock(void)
|
||||
STORAGE_TEST_CHECK(badok, "TC-STO-03 injected blocks still reported bad");
|
||||
|
||||
f_unlink("bbt.dat");
|
||||
/* 注意:注入的坏块已持久化,测试设备专用;如需恢复需重建 BBT / 重新格式化 */
|
||||
/* 注意:注入的坏块已持久化,测试设备专用;如需恢复需重建 BBT / 重新格式化
|
||||
* (配套 TC-STO-04 恢复测试:storage_test.h 启用 ENABLE_STORAGE_RECOVERY_TESTS
|
||||
* 后跑一次套件,即可清除运行时注入坏块 + 清 dhara map 回出厂态) */
|
||||
}
|
||||
|
||||
/* TC-STO-05: 文件名/路径合法性校验(守护 ".fschk 无限重格式化" 真根因)
|
||||
* 本移植 FF_USE_LFN=0,只支持严格 8.3 短名(主名≤8、扩展≤3、不以点开头)。
|
||||
* 非法名字 f_open 必返 FR_INVALID_NAME(纯 RAM 名字判定、不碰盘);合法但
|
||||
* 不存在的名字返 FR_NO_FILE。本测试断言两类严格可区分——一旦哪天有人把
|
||||
* FR_INVALID_NAME 误归入"卷损坏"自愈集合,这条测试就是最后的机械防线。
|
||||
* (详见 docs/问题记录/GD5F2GQ5UE_Trap_Records.md Trap 05 / AGENTS.md)
|
||||
*/
|
||||
static void storage_test_name_validation(void)
|
||||
{
|
||||
uint32_t i;
|
||||
int gok = 1;
|
||||
int bok = 1;
|
||||
|
||||
/* 合法 8.3:FA_READ 打开 → FR_OK(存在) 或 FR_NO_FILE(不存在),均非 INVALID */
|
||||
static const char *good[] = {
|
||||
"fschk.tmp", /* 修复后的探针名(名5+扩展3) */
|
||||
"config.ini", /* 名6+扩展3 */
|
||||
"12345678.txt", /* 主名 8 / 扩展 3 上限 */
|
||||
"A.TXT", /* 最小合法名 */
|
||||
"NOEXT", /* 无扩展 */
|
||||
"1.23", /* 数字名 */
|
||||
"run.log"
|
||||
};
|
||||
/* 非法:FF_USE_LFN=0 下 create_short 必拒 → FR_INVALID_NAME */
|
||||
static const char *bad[] = {
|
||||
".fschk", /* 事故根因:点开头(点后当扩展域,超 3 上限) */
|
||||
".hidden", /* 点开头隐藏名风格 */
|
||||
"123456789", /* 主名 9 > 8 */
|
||||
"toolongname.txt", /* 主名 > 8 */
|
||||
"a.toolongext", /* 扩展 > 3 */
|
||||
"bad?char.txt", /* 非法字符 ? */
|
||||
"star*name", /* * */
|
||||
"col:on", /* : */
|
||||
"lt<gt>val", /* < > */
|
||||
"pipe|name" /* | */
|
||||
};
|
||||
|
||||
DBG_INFO("=== Storage Test: TC-STO-05 Filename validation ===");
|
||||
|
||||
if (f_mount(&fs, "", 1) != FR_OK) {
|
||||
STORAGE_TEST_CHECK(0, "TC-STO-05 mount");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < (uint32_t)(sizeof(good) / sizeof(good[0])); i++) {
|
||||
FRESULT r = f_open(&fil, good[i], FA_READ);
|
||||
if (r == FR_OK) {
|
||||
f_close(&fil);
|
||||
}
|
||||
if (r == FR_INVALID_NAME) {
|
||||
gok = 0;
|
||||
DBG_ERROR(" valid name wrongly rejected: '%s'", good[i]);
|
||||
}
|
||||
}
|
||||
STORAGE_TEST_CHECK(gok, "TC-STO-05 valid 8.3 names accepted");
|
||||
|
||||
for (i = 0; i < (uint32_t)(sizeof(bad) / sizeof(bad[0])); i++) {
|
||||
FRESULT r = f_open(&fil, bad[i], FA_READ);
|
||||
if (r == FR_OK) {
|
||||
f_close(&fil);
|
||||
}
|
||||
/* 含 ':' 的名字被 FatFs 先解析为盘符前缀 → FR_INVALID_DRIVE(11)
|
||||
* 同样属合法拒绝(台架实测 'col:on' fr=11),与 INVALID 同等待遇 */
|
||||
if ((r != FR_INVALID_NAME) &&
|
||||
!((r == FR_INVALID_DRIVE) && (strchr(bad[i], ':') != NULL))) {
|
||||
bok = 0;
|
||||
DBG_ERROR(" invalid name NOT rejected: '%s' -> fr=%d", bad[i], (int)r);
|
||||
}
|
||||
}
|
||||
STORAGE_TEST_CHECK(bok, "TC-STO-05 invalid names rejected (FR_INVALID_NAME)");
|
||||
}
|
||||
|
||||
/* TC-STO-06: 打开模式与写回字节数语义(守护 FA_OPEN_APPEND / 短写陷阱)
|
||||
* 本移植 FA_OPEN_APPEND 不含 FA_WRITE → 不带写位打开 f_write 必返 FR_DENIED;
|
||||
* 追加写必须 FA_WRITE|FA_OPEN_APPEND。另 f_write 簇耗尽返 FR_OK+短写(无错误
|
||||
* 码),判成败必须校验写回字节数。锁定这两条移植专有语义防回归。
|
||||
*/
|
||||
static void storage_test_open_modes(void)
|
||||
{
|
||||
UINT bw;
|
||||
FRESULT r;
|
||||
|
||||
DBG_INFO("=== Storage Test: TC-STO-06 Open-mode semantics ===");
|
||||
|
||||
if (f_mount(&fs, "", 1) != FR_OK) {
|
||||
STORAGE_TEST_CHECK(0, "TC-STO-06 mount");
|
||||
return;
|
||||
}
|
||||
(void)f_unlink("mode.tmp");
|
||||
|
||||
/* 1) 建一个含初始内容的文件 */
|
||||
r = f_open(&fil, "mode.tmp", FA_CREATE_ALWAYS | FA_WRITE);
|
||||
STORAGE_TEST_CHECK(r == FR_OK, "TC-STO-06 create base file");
|
||||
if (r == FR_OK) {
|
||||
f_write(&fil, "abc", 3, &bw);
|
||||
f_close(&fil);
|
||||
}
|
||||
|
||||
/* 2) FA_OPEN_APPEND(无 FA_WRITE)→ 写必返 FR_DENIED */
|
||||
r = f_open(&fil, "mode.tmp", FA_OPEN_APPEND);
|
||||
STORAGE_TEST_CHECK(r == FR_OK, "TC-STO-06 open append(no write)");
|
||||
if (r == FR_OK) {
|
||||
FRESULT wr = f_write(&fil, "xyz", 3, &bw);
|
||||
STORAGE_TEST_CHECK(wr == FR_DENIED,
|
||||
"TC-STO-06 append-no-write must DENY (fr=%d)", (int)wr);
|
||||
f_close(&fil);
|
||||
}
|
||||
|
||||
/* 3) FA_WRITE|FA_OPEN_APPEND → 追加成功且字节数正确 */
|
||||
r = f_open(&fil, "mode.tmp", FA_WRITE | FA_OPEN_APPEND);
|
||||
STORAGE_TEST_CHECK(r == FR_OK, "TC-STO-06 open write|append");
|
||||
if (r == FR_OK) {
|
||||
(void)f_write(&fil, "xyz", 3, &bw);
|
||||
STORAGE_TEST_CHECK(bw == 3, "TC-STO-06 append byte-count (%u)", bw);
|
||||
f_close(&fil);
|
||||
}
|
||||
|
||||
/* 4) 只读打开后写 → 必返 FR_DENIED(读句柄不可写) */
|
||||
r = f_open(&fil, "mode.tmp", FA_READ);
|
||||
STORAGE_TEST_CHECK(r == FR_OK, "TC-STO-06 open read-only");
|
||||
if (r == FR_OK) {
|
||||
FRESULT wr = f_write(&fil, "q", 1, &bw);
|
||||
STORAGE_TEST_CHECK(wr == FR_DENIED,
|
||||
"TC-STO-06 read-only write must DENY (fr=%d)", (int)wr);
|
||||
f_close(&fil);
|
||||
}
|
||||
|
||||
(void)f_unlink("mode.tmp");
|
||||
}
|
||||
#endif /* !ENABLE_STORAGE_RECOVERY_TESTS: 共享缓冲 + 正常测试函数 */
|
||||
|
||||
#ifdef ENABLE_STORAGE_RECOVERY_TESTS
|
||||
static void storage_test_recover(void);
|
||||
#endif
|
||||
|
||||
void storage_test_run(void)
|
||||
#ifndef ENABLE_STORAGE_RECOVERY_TESTS
|
||||
/* 正常存储测试套件主体(恢复模式见文件末尾 storage_test_run 分发) */
|
||||
static void storage_test_run_normal(void)
|
||||
{
|
||||
static FATFS fs;
|
||||
static FIL fil;
|
||||
static uint8_t work[FF_MAX_SS];
|
||||
char read_buf[64];
|
||||
const char *test_str = "Hello FatFS + dhara FTL!";
|
||||
@@ -341,7 +479,11 @@ void storage_test_run(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* ==================== 存储集成测试(TC-STO-01~03) ==================== */
|
||||
/* ==================== 存储集成测试(TC-STO-05~06 契约 + 01~03 集成) ========== */
|
||||
|
||||
/* 纯语义契约测试(非破坏性,先跑):名字合法性 + 打开模式 */
|
||||
storage_test_name_validation();
|
||||
storage_test_open_modes();
|
||||
|
||||
storage_test_powerloss();
|
||||
storage_test_largefile();
|
||||
@@ -355,6 +497,24 @@ void storage_test_run(void)
|
||||
|
||||
STORAGE_TEST_REPORT("Storage Tests");
|
||||
}
|
||||
#endif /* !ENABLE_STORAGE_RECOVERY_TESTS */
|
||||
|
||||
/*
|
||||
* 套件总入口分发。恢复模式(storage_test.h 打开 ENABLE_STORAGE_RECOVERY_TESTS)
|
||||
* = 专用维护构建:重建 BBT(清除运行时误标坏块)+ 清 dhara map 后直接返回,
|
||||
* 不在受污染介质上继续跑其余测试(2026-09-20:CCM 首轮实验中 DMA 够不到栈上
|
||||
* 小缓冲,随机块被误标坏并持久化,journal 引用到即静默卡死——恢复模式即为其
|
||||
* 清账手段)。恢复完成后重新注释该宏、编译正常套件即可。
|
||||
*/
|
||||
void storage_test_run(void)
|
||||
{
|
||||
#ifdef ENABLE_STORAGE_RECOVERY_TESTS
|
||||
storage_test_recover();
|
||||
STORAGE_TEST_REPORT("Storage Recovery");
|
||||
#else
|
||||
storage_test_run_normal();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ENABLE_STORAGE_RECOVERY_TESTS
|
||||
/* TC-STO-04: 重建 BBT + 重新格式化(恢复 TC-STO-03 注入的坏块)
|
||||
|
||||
Reference in New Issue
Block a user