GD5F 补 DMA 守卫负路径用例 TC-704/705,导出阈值宏并对齐测试指南
This commit is contained in:
+75
-18
@@ -2,8 +2,9 @@
|
||||
* 模块名称:GD5F2GQ5UE Driver Test Task
|
||||
* 模块功能:GD5F2GQ5UE 驱动全阶段测试入口,统一在 defaultTask 上下文(同步阻塞)
|
||||
* 中运行。各阶段由 gd5f_test.h 中的 ENABLE_GD5F_PHASE*_TESTS 宏独立开关,
|
||||
* 覆盖 init/read_id/reset、BBT、页读写、块擦除、ECC、SPI 原语、DMA 边界、
|
||||
* FTL 与 FatFS。所有结果通过 GD5F_TEST_CHECK / GD5F_TEST_REPORT 输出串口。
|
||||
* 覆盖 init/read_id/reset、BBT、页读写、块擦除、ECC、SPI 原语、DMA 边界与
|
||||
* DMA 可达性守卫负路径、FTL 与 FatFS。所有结果通过 GD5F_TEST_CHECK /
|
||||
* GD5F_TEST_REPORT 输出串口。
|
||||
* 作者:王建锋
|
||||
* 创建日期:2026-08-26
|
||||
*
|
||||
@@ -12,6 +13,7 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include "FreeRTOS.h"
|
||||
#include "test_config.h"
|
||||
#include "gd5f_test.h"
|
||||
#include "nand_ftl.h"
|
||||
@@ -30,6 +32,10 @@ gd5f_test_stats_t g_gd5f_test_stats;
|
||||
static uint8_t s_wbuf[GD5F_PAGE_SIZE * 2];
|
||||
static uint8_t s_rbuf[GD5F_PAGE_SIZE * 2];
|
||||
|
||||
/* CCM(SRAM3)区间:DMA1/DMA2 物理不可达,用于守卫负路径的前提判定 */
|
||||
#define GD5F_TEST_CCM_BASE 0x10000000UL
|
||||
#define GD5F_TEST_CCM_END 0x10010000UL
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* 辅助:从最高块向下寻找连续 n 个好块,返回其中最高块号;找不到返回 GD5F_TOTAL_BLOCKS
|
||||
* ------------------------------------------------------------------- */
|
||||
@@ -514,7 +520,7 @@ static void gd5f_phase6(void)
|
||||
#endif /* ENABLE_GD5F_PHASE6_TESTS */
|
||||
|
||||
/* -------------------------------------------------------------------
|
||||
* Phase 7 — DMA 边界(阈值 32 字节)
|
||||
* Phase 7 — DMA 边界与 DMA 可达性守卫(阈值见 GD5F_DMA_THRESHOLD)
|
||||
* ------------------------------------------------------------------- */
|
||||
#ifdef ENABLE_GD5F_PHASE7_TESTS
|
||||
static void gd5f_phase7(void)
|
||||
@@ -522,37 +528,42 @@ static void gd5f_phase7(void)
|
||||
uint32_t blk;
|
||||
int32_t base;
|
||||
int32_t ret, ok, i;
|
||||
uint8_t *p_heap; /* 堆缓冲探针(堆驻留 CCM → DMA 不可达) */
|
||||
uintptr_t p_addr;
|
||||
|
||||
DBG_INFO("=== GD5F Phase 7: DMA boundary (threshold 32) ===");
|
||||
DBG_INFO("=== GD5F Phase 7: DMA boundary (threshold %d) ===",
|
||||
(int)GD5F_DMA_THRESHOLD);
|
||||
blk = gd5f_find_run(1);
|
||||
base = (int32_t)blk * GD5F_BLOCK_SIZE;
|
||||
|
||||
/* TC-GD5F-701: size=32 轮询路径 */
|
||||
/* TC-GD5F-701: 阈值下界(= 阈值,轮询路径) */
|
||||
gd5f2gq5ue_erase(base, GD5F_BLOCK_SIZE);
|
||||
for (i = 0; i < 32; i++) {
|
||||
for (i = 0; i < (int32_t)GD5F_DMA_THRESHOLD; i++) {
|
||||
s_wbuf[i] = (uint8_t)(i + 0x10);
|
||||
}
|
||||
ret = gd5f2gq5ue_write(base, s_wbuf, 32);
|
||||
GD5F_TEST_CHECK(ret == GD5F_OK, "TC-GD5F-701 write(32) ret=%d", ret);
|
||||
memset(s_rbuf, 0, 32);
|
||||
ret = gd5f2gq5ue_read(base, s_rbuf, 32);
|
||||
ret = gd5f2gq5ue_write(base, s_wbuf, GD5F_DMA_THRESHOLD);
|
||||
GD5F_TEST_CHECK(ret == GD5F_OK, "TC-GD5F-701 write(%d) ret=%d",
|
||||
(int)GD5F_DMA_THRESHOLD, ret);
|
||||
memset(s_rbuf, 0, GD5F_DMA_THRESHOLD);
|
||||
ret = gd5f2gq5ue_read(base, s_rbuf, GD5F_DMA_THRESHOLD);
|
||||
ok = 1;
|
||||
for (i = 0; i < 32; i++) {
|
||||
for (i = 0; i < (int32_t)GD5F_DMA_THRESHOLD; i++) {
|
||||
if (s_rbuf[i] != (uint8_t)(i + 0x10)) { ok = 0; break; }
|
||||
}
|
||||
GD5F_TEST_CHECK(ok, "TC-GD5F-701 polling path %s", ok ? "OK" : "MISMATCH");
|
||||
|
||||
/* TC-GD5F-702: size=33 DMA 路径 */
|
||||
/* TC-GD5F-702: 阈值上界(= 阈值+1,DMA 路径,缓冲在 SRAM 静态区) */
|
||||
gd5f2gq5ue_erase(base, GD5F_BLOCK_SIZE);
|
||||
for (i = 0; i < 33; i++) {
|
||||
for (i = 0; i < (int32_t)GD5F_DMA_THRESHOLD + 1; i++) {
|
||||
s_wbuf[i] = (uint8_t)(i + 0x20);
|
||||
}
|
||||
ret = gd5f2gq5ue_write(base, s_wbuf, 33);
|
||||
GD5F_TEST_CHECK(ret == GD5F_OK, "TC-GD5F-702 write(33) ret=%d", ret);
|
||||
memset(s_rbuf, 0, 33);
|
||||
ret = gd5f2gq5ue_read(base, s_rbuf, 33);
|
||||
ret = gd5f2gq5ue_write(base, s_wbuf, GD5F_DMA_THRESHOLD + 1U);
|
||||
GD5F_TEST_CHECK(ret == GD5F_OK, "TC-GD5F-702 write(%d) ret=%d",
|
||||
(int)GD5F_DMA_THRESHOLD + 1, ret);
|
||||
memset(s_rbuf, 0, GD5F_DMA_THRESHOLD + 1U);
|
||||
ret = gd5f2gq5ue_read(base, s_rbuf, GD5F_DMA_THRESHOLD + 1U);
|
||||
ok = 1;
|
||||
for (i = 0; i < 33; i++) {
|
||||
for (i = 0; i < (int32_t)GD5F_DMA_THRESHOLD + 1; i++) {
|
||||
if (s_rbuf[i] != (uint8_t)(i + 0x20)) { ok = 0; break; }
|
||||
}
|
||||
GD5F_TEST_CHECK(ok, "TC-GD5F-702 DMA path %s", ok ? "OK" : "MISMATCH");
|
||||
@@ -571,6 +582,52 @@ static void gd5f_phase7(void)
|
||||
if (s_rbuf[i] != (uint8_t)(i & 0xFF)) { ok = 0; break; }
|
||||
}
|
||||
GD5F_TEST_CHECK(ok, "TC-GD5F-703 DMA whole page %s", ok ? "OK" : "MISMATCH");
|
||||
|
||||
/* ================= DMA 可达性守卫(负路径) =================
|
||||
* 探针缓冲取自 FreeRTOS 堆:堆驻留 CCM(0x10000000),DMA1/DMA2 不可达。
|
||||
* 期望:驱动守卫拒绝该缓冲 → 回落 CPU 轮询 → 数据仍正确落位(轮询可写 CCM)。
|
||||
* 判定依据(本板实证):若误走 DMA,CCM 内容不会改变(静默不落地),
|
||||
* 故"数据与参考一致"即证明回落确实发生——非仅未报错。
|
||||
* 堆不在 CCM 时本用例前提不成立(改为验证正路径无意义),跳过并记录。 */
|
||||
p_heap = (uint8_t *)pvPortMalloc(GD5F_PAGE_SIZE);
|
||||
if (p_heap == NULL) {
|
||||
GD5F_TEST_CHECK(0, "TC-GD5F-704 pvPortMalloc(2048) failed");
|
||||
} else {
|
||||
p_addr = (uintptr_t)p_heap;
|
||||
if ((p_addr < GD5F_TEST_CCM_BASE) || (p_addr >= GD5F_TEST_CCM_END)) {
|
||||
DBG_INFO("TC-GD5F-704/705 SKIP: heap buf not in CCM (p=0x%08lX)",
|
||||
(unsigned long)p_addr);
|
||||
} else {
|
||||
/* TC-GD5F-704: 读方向 —— 目的缓冲在 CCM,应回落轮询 */
|
||||
memset(s_rbuf, 0, GD5F_PAGE_SIZE);
|
||||
(void)gd5f2gq5ue_read(base, s_rbuf, GD5F_PAGE_SIZE); /* 参考读(SRAM 静态) */
|
||||
for (i = 0; i < GD5F_PAGE_SIZE; i++) {
|
||||
p_heap[i] = (uint8_t)~s_rbuf[i]; /* 预填参考值反码:未落数必失配 */
|
||||
}
|
||||
ret = gd5f2gq5ue_read(base, p_heap, GD5F_PAGE_SIZE);
|
||||
ok = (ret == GD5F_OK) &&
|
||||
(memcmp(p_heap, s_rbuf, GD5F_PAGE_SIZE) == 0);
|
||||
GD5F_TEST_CHECK(ok, "TC-GD5F-704 CCM(heap) rx poll fallback %s",
|
||||
ok ? "OK" : "MISMATCH");
|
||||
|
||||
/* TC-GD5F-705: 写方向 —— 源缓冲在 CCM,应回落轮询 */
|
||||
gd5f2gq5ue_erase(base, GD5F_BLOCK_SIZE);
|
||||
for (i = 0; i < GD5F_PAGE_SIZE; i++) {
|
||||
p_heap[i] = (uint8_t)(i ^ 0x5A);
|
||||
}
|
||||
ret = gd5f2gq5ue_write(base, p_heap, GD5F_PAGE_SIZE);
|
||||
GD5F_TEST_CHECK(ret == GD5F_OK, "TC-GD5F-705 write(CCM src) ret=%d", ret);
|
||||
memset(s_rbuf, 0, GD5F_PAGE_SIZE);
|
||||
ret = gd5f2gq5ue_read(base, s_rbuf, GD5F_PAGE_SIZE);
|
||||
ok = 1;
|
||||
for (i = 0; i < GD5F_PAGE_SIZE; i++) {
|
||||
if (s_rbuf[i] != (uint8_t)(i ^ 0x5A)) { ok = 0; break; }
|
||||
}
|
||||
GD5F_TEST_CHECK(ok, "TC-GD5F-705 CCM(heap) tx poll fallback %s",
|
||||
ok ? "OK" : "MISMATCH");
|
||||
}
|
||||
vPortFree(p_heap);
|
||||
}
|
||||
}
|
||||
#endif /* ENABLE_GD5F_PHASE7_TESTS */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user