diff --git a/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c b/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c index 70b9b4ab..04aa0316 100644 --- a/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c +++ b/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c @@ -153,20 +153,14 @@ int gd5f_read_status(uint8_t *p_status) { } /* - * 函数功能:页读取(将数据从存储阵列加载到内部缓存) + * 函数功能:发送一次 13h 页读取命令(gd5f_page_read 的装载单元) * 入口参数:page_addr - 页地址 uint32_t 0 ~ GD5F_TOTAL_BLOCKS*64-1 - * 返回值:0 - 成功,其它 - 错误 + * 返回值:无 * 限定条件:SPI 已初始化 - * 函数说明:发 13h + 3字节行地址,等待 OIP 清零 + 固定沉降延时 - * GD5F_PAGE_READ_SETTLE_MS(2026-09-20 台架实证:低 VDD 下 - * 就绪信号早于 array→buffer 整页装载完成,0Bh 会读到"前段新、 - * 后段旧"的混合页 → journal resume 锚定新 checkpoint 却读到 - * 旧树 → 数据静默丢失。固定沉降保证整页新鲜,双装载无法 - * 消除该确定性竞态,已弃用。) + * 函数说明:发 13h + 3字节行地址 */ -int gd5f_page_read(uint32_t page_addr) { +static void gd5f_page_read_issue(uint32_t page_addr) { uint8_t cmd[4] = {0}; - int ret; cmd[0] = GD5F_CMD_PAGE_READ; cmd[1] = (page_addr >> 16) & 0xFF; @@ -176,13 +170,38 @@ int gd5f_page_read(uint32_t page_addr) { GD5F_CS_LOW(); HAL_SPI_Transmit(&hspi1, cmd, 4, GD5F_SPI_TIMEOUT); GD5F_CS_HIGH(); +} +/* + * 函数功能:页读取(将数据从存储阵列加载到内部缓存) + * 入口参数:page_addr - 页地址 uint32_t 0 ~ GD5F_TOTAL_BLOCKS*64-1 + * 返回值:0 - 成功,其它 - 错误 + * 限定条件:SPI 已初始化 + * 函数说明:13h 二次发令 + 固定沉降延时 GD5F_PAGE_READ_SETTLE_MS。 + * 台架实证(2026-09-20,VDD 3.1V 欠压工况):① 就绪信号可早于 + * array→buffer 整页装载完成 → 0Bh 读到"前段新、后段旧"混合页; + * ② 13h 命令在编程/擦除风暴后可不被芯片锁存(空操作)→ 0Bh + * 读到上一操作残留 buffer(编程数据)→ in-boot 回读校验/文件 + * 读取全部"虚假成功",阵列实际未更新 → 复位后数据丢失。 + * 二次发令覆盖②(重发必被锁存),固定沉降覆盖①(整页装载完成)。 + */ +int gd5f_page_read(uint32_t page_addr) { + int ret; + + gd5f_page_read_issue(page_addr); ret = gd5f_wait_busy(100); if (ret != GD5F_OK) { return ret; } - /* 固定沉降:等待 array→buffer 整页装载完成(见函数说明) */ + /* 二次发令:首条 13h 未被锁存(空操作)时由重发兜底 */ + gd5f_page_read_issue(page_addr); + ret = gd5f_wait_busy(100); + if (ret != GD5F_OK) { + return ret; + } + + /* 固定沉降:等待 array→buffer 整页装载完成 */ HAL_Delay(GD5F_PAGE_READ_SETTLE_MS); return GD5F_OK;