From d48be81478a1c47390979a68db0505eff3fe6906 Mon Sep 17 00:00:00 2001 From: wandering1 <1624155937@qq.com> Date: Tue, 21 Jul 2026 21:48:23 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=A0=E9=99=A4FlashDB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AGENTS.md | 28 +- Drivers/BSP/GD5F2GQ5UE/fal_cfg.h | 63 --- Drivers/BSP/GD5F2GQ5UE/fal_flash_gd5f2gq5ue.c | 69 --- Drivers/BSP/GD5F2GQ5UE/fdb_cfg.h | 40 -- Drivers/BSP/GD5F2GQ5UE/nand_ftl.c | 4 +- Lib/FlashDB | 1 - MDK-ARM/STM32F407-Demo.uvprojx | 47 +- MDK-ARM/build_log.txt | 86 ++-- Src/freertos.c | 41 -- docs/FlashDB使用说明.md | 400 ------------------ docs/STM32F4-Base存储架构说明.md | 294 +++---------- 11 files changed, 102 insertions(+), 971 deletions(-) delete mode 100644 Drivers/BSP/GD5F2GQ5UE/fal_cfg.h delete mode 100644 Drivers/BSP/GD5F2GQ5UE/fal_flash_gd5f2gq5ue.c delete mode 100644 Drivers/BSP/GD5F2GQ5UE/fdb_cfg.h delete mode 160000 Lib/FlashDB delete mode 100644 docs/FlashDB使用说明.md diff --git a/AGENTS.md b/AGENTS.md index d4db6f1..784a567 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,7 +4,7 @@ ## 项目概述 -STM32F407ZGTx (Cortex-M4 FPU) 基础固件项目,集成 CH395F 以太网控制器 SPI 驱动、GD5F2GQ5UE SPI NAND Flash 存储(含 FlashDB KVDB/TSDB 数据库)和 TPAFE5160 16位8通道同步采样 ADC 并行接口驱动。 +STM32F407ZGTx (Cortex-M4 FPU) 基础固件项目,集成 CH395F 以太网控制器 SPI 驱动、GD5F2GQ5UE SPI NAND Flash 存储(dhara FTL + FatFS 文件系统)和 TPAFE5160 16位8通道同步采样 ADC 并行接口驱动。 ## 目录结构 @@ -24,17 +24,13 @@ STM32F4-Base/ │ │ │ └── net_select.c # select/poll 实现 │ │ ├── GD5F2GQ5UE/ # GD5F2GQ5UE NAND Flash 驱动(手写) │ │ │ ├── gd5f2gq5ue.h/c # 底层 SPI 驱动 -│ │ │ ├── fal_flash_gd5f2gq5ue.c # FAL 设备适配层 -│ │ │ ├── fal_cfg.h # FAL 设备表 + 分区表 -│ │ │ └── fdb_cfg.h # FlashDB 功能配置 +│ │ │ └── nand_ftl.h/c # dhara FTL + FatFS diskio 适配层 │ │ └── TPAFE5160/ # TPAFE5160 ADC 并行接口驱动(手写) │ ├── STM32F4xx_HAL_Driver/ # ST HAL 库(CubeMX 生成) │ └── CMSIS/ # ARM CMSIS(CubeMX 生成) ├── Lib/ -│ └── FlashDB/ # FlashDB 数据库库(v2.2.99) -│ ├── src/ # FlashDB 核心源码 -│ ├── inc/ # FlashDB 头文件 -│ └── port/fal/ # FAL 抽象层 +│ ├── dhara/ # dhara FTL (Flash Translation Layer) +│ └── FatFs/ # FatFs 文件系统 (v0.15) ├── MDK-ARM/ # Keil MDK 工程文件 ├── docs/ # 参考文档 └── STM32F407-Demo.ioc # STM32CubeMX 项目源文件 @@ -49,7 +45,7 @@ STM32F4-Base/ | `Drivers/BSP/NET/net_socket.c/h` | BSD Socket API 网络抽象层 | | `Drivers/BSP/NET/net_select.c/h` | select/poll I/O 多路复用 | | `Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c/h` | GD5F2GQ5UE NAND Flash SPI 驱动 | -| `Drivers/BSP/GD5F2GQ5UE/fal_flash_gd5f2gq5ue.c` | FAL 设备适配层 | +| `Drivers/BSP/GD5F2GQ5UE/nand_ftl.c` | dhara FTL + FatFS diskio 适配层 | | `Drivers/BSP/TPAFE5160/tpafe5160.c/h` | TPAFE5160 ADC 并行接口驱动 | | `Src/freertos.c` | FreeRTOS task 创建和任务函数(CubeMX 生成 + 手写) | | `Inc/FreeRTOSConfig.h` | FreeRTOS 内核配置 | @@ -87,7 +83,7 @@ STM32F4-Base/ ``` HAL_Init() → SystemClock_Config() → MX_GPIO_Init() → MX_USART1_UART_Init() → MX_SPI2_Init() → MX_SPI1_Init() -→ gd5f2gq5ue_init() → fdb_kvdb_init() → [USER CODE: net_init + TCP listen + 其他外设初始化] +→ gd5f2gq5ue_init() → [USER CODE: net_init + TCP listen + 其他外设初始化] → osKernelInitialize() → MX_FREERTOS_Init() → osKernelStart() ← FreeRTOS 调度器启动 → [FreeRTOS tasks: defaultTask, netTask 运行] ``` @@ -106,12 +102,11 @@ HAL_Init() → SystemClock_Config() → MX_GPIO_Init() → MX_USART1_UART_Init() ## 注意 - `Inc/` 和 `Src/` 中 CubeMX 生成的文件带有 `USER CODE BEGIN`/`END` 标记,自定义代码应写在这些区域之间 -- `ch395f.c/h`、`gd5f2gq5ue.c/h`、`fal_flash_gd5f2gq5ue.c` 为纯手工代码,不受 CubeMX 保护 +- `ch395f.c/h`、`gd5f2gq5ue.c/h`、`nand_ftl.c/h` 为纯手工代码,不受 CubeMX 保护 - `tpafe5160.c/h` 为纯手工代码,不受 CubeMX 保护 - CH395F 每次 SPI 事务需调用 `ch395f_spi_begin()` / `ch395f_spi_end()` 包裹 - GD5F2GQ5UE 的 `gd5f2gq5ue.c` 中声明了 `extern SPI_HandleTypeDef hspi1`,需确保 SPI1 已初始化 -- FlashDB 使用 FAL 模式,`fdb_cfg.h` 中定义 `FDB_USING_FAL_MODE`,`fal_cfg.h` 中定义分区表 -- FlashDB 详细使用说明见 `FlashDB使用说明.md` + - `sd2506.c/h` 为纯手工代码,不受 CubeMX 保护 - FreeRTOS Kernel V10.3.1 via CMSIS-RTOS V2 接口,HAL 时基使用 TIM7(非 SysTick,避免与 FreeRTOS 冲突) - NVIC 优先级分组 4 位,外设中断优先级全部 ≥ `configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY`(5),确保 ISR 可调 FreeRTOS API @@ -157,13 +152,10 @@ HAL_Init() → SystemClock_Config() → MX_GPIO_Init() → MX_USART1_UART_Init() | 分区名 | 偏移 | 大小 | 块范围 | 用途 | |--------|------|------|--------|------| -| fdb_kvdb1 | 0 | 64MB | Block 0~511 | FlashDB KVDB 键值数据库 | -| fdb_tsdb1 | 64MB | 64MB | Block 512~1023 | FlashDB TSDB 时序数据库 | | ftl_fatfs | 128MB | 128MB | Block 1024~2047 | dhara FTL + FatFS 文件系统 | -- FlashDB 通过 FAL 层访问 `fdb_kvdb1` / `fdb_tsdb1`(`Drivers/BSP/GD5F2GQ5UE/fal_cfg.h`) -- FatFS 通过 dhara FTL 访问 `ftl_fatfs` 分区,`nand_ftl.c` 中 `FTL_START_BLOCK = FTL_FATFS_OFFSET / GD5F_BLOCK_SIZE`(与 `fal_cfg.h` 联动) -- 三个分区物理隔离,互不重叠,分区配置统一在 `fal_cfg.h:25-30` +- FatFS 通过 dhara FTL 访问 `ftl_fatfs` 分区,`nand_ftl.c` 中 `FTL_START_BLOCK = FTL_FATFS_OFFSET / GD5F_BLOCK_SIZE` +- Block 0~1023(128MB)预留,可供后续扩展 ## TPAFE5160 驱动关键点 diff --git a/Drivers/BSP/GD5F2GQ5UE/fal_cfg.h b/Drivers/BSP/GD5F2GQ5UE/fal_cfg.h deleted file mode 100644 index c94faad..0000000 --- a/Drivers/BSP/GD5F2GQ5UE/fal_cfg.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef __FAL_CFG_H -#define __FAL_CFG_H - -/* - * 模块名称:FAL 配置 - * 模块功能:定义 Flash 物理分区布局和 FAL 设备/分区表 - * 适用平台:STM32F407ZGT6 - * 作者:王建锋 - * 创建日期:2026-07-16 - * 修改记录: - * 2026-07-20 王建锋 统一分区配置,添加 FTL 分区宏供 nand_ftl.c 使用 - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* ================== 物理分区布局(256MB GD5F2GQ5UE) ================== */ -/* - * 分区名 偏移 大小 块范围 用途 - * fdb_kvdb1 0 64MB Block 0~511 FlashDB KVDB - * fdb_tsdb1 64MB 64MB Block 512~1023 FlashDB TSDB - * ftl_fatfs 128MB 128MB Block 1024~2047 dhara FTL + FatFS - */ -#define FDB_KVDB1_OFFSET 0 -#define FDB_KVDB1_SIZE (64 * 1024 * 1024) -#define FDB_TSDB1_OFFSET (FDB_KVDB1_OFFSET + FDB_KVDB1_SIZE) -#define FDB_TSDB1_SIZE (64 * 1024 * 1024) -#define FTL_FATFS_OFFSET (FDB_TSDB1_OFFSET + FDB_TSDB1_SIZE) -#define FTL_FATFS_SIZE (128 * 1024 * 1024) - -/* ====================== FAL 配置(需 FAL 头文件) ====================== */ - -#define FAL_DEBUG 0 - -/* 启用分区表配置(FAL 库要求此宏) */ -#define FAL_PART_HAS_TABLE_CFG - -/* ======================== Flash 设备表 ======================== */ - -extern const struct fal_flash_dev g_gd5f2gq5ue_flash; - -#define FAL_FLASH_DEV_TABLE \ -{ \ - &g_gd5f2gq5ue_flash, \ -} - -/* ======================== 分区表 ======================== */ - -#ifdef FAL_PART_HAS_TABLE_CFG -#define FAL_PART_TABLE \ -{ \ - {FAL_PART_MAGIC_WORD, "fdb_kvdb1", "gd5f2gq5ue", FDB_KVDB1_OFFSET, FDB_KVDB1_SIZE, 0}, \ - {FAL_PART_MAGIC_WORD, "fdb_tsdb1", "gd5f2gq5ue", FDB_TSDB1_OFFSET, FDB_TSDB1_SIZE, 0}, \ -} -#endif /* FAL_PART_HAS_TABLE_CFG */ - -#ifdef __cplusplus -} -#endif - -#endif /* __FAL_CFG_H */ - diff --git a/Drivers/BSP/GD5F2GQ5UE/fal_flash_gd5f2gq5ue.c b/Drivers/BSP/GD5F2GQ5UE/fal_flash_gd5f2gq5ue.c deleted file mode 100644 index 5a086f5..0000000 --- a/Drivers/BSP/GD5F2GQ5UE/fal_flash_gd5f2gq5ue.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 模块名称:FAL Flash 设备适配 - * 模块功能:将 GD5F2GQ5UE 驱动接口适配?FAL 框架 - * 适用平台:STM32F407ZGT6 - * 作者:王建? * 创建日期?026-07-16 - * 修改记录? * 2026-07-16 王建? 创建初始版本 - */ - -/* 头文件包含区 */ -#include "fal_def.h" -#include "gd5f2gq5ue.h" - -/* ======================== FAL 操作函数适配 ======================== */ - -/* - * 函数功能:Flash 设备初始化适配 - * 入口参数:无 - * 返回值:0 - 成功,其?- 错误? * 限定条件:SPI ?GPIO 已由 CubeMX 初始化完? * 函数说明:调用底层驱动的初始化函? */ -static int gd5f_fal_init(void) { - return gd5f2gq5ue_init(); -} - -/* - * 函数功能:Flash 读取适配 - * 入口参数:offset - 起始字节偏移 long - * p_buf - 数据缓冲? uint8_t* - * size - 读取字节? size_t - * 返回值:0 - 成功,其?- 错误? * 限定条件:gd5f_fal_init() 已成功调? * 函数说明:直接转发到底层驱动的读取函? */ -static int gd5f_fal_read(long offset, uint8_t *p_buf, size_t size) { - return gd5f2gq5ue_read(offset, p_buf, size); -} - -/* - * 函数功能:Flash 写入适配 - * 入口参数:offset - 起始字节偏移 long - * p_buf - 数据缓冲? const uint8_t* - * size - 写入字节? size_t - * 返回值:0 - 成功,其?- 错误? * 限定条件:目标区域已擦除 - * 函数说明:直接转发到底层驱动的写入函? */ -static int gd5f_fal_write(long offset, const uint8_t *p_buf, size_t size) { - return gd5f2gq5ue_write(offset, p_buf, size); -} - -/* - * 函数功能:Flash 擦除适配 - * 入口参数:offset - 起始字节偏移 long - * size - 擦除字节? size_t - * 返回值:0 - 成功,其?- 错误? * 限定条件:gd5f_fal_init() 已成功调? * 函数说明:直接转发到底层驱动的擦除函? */ -static int gd5f_fal_erase(long offset, size_t size) { - return gd5f2gq5ue_erase(offset, size); -} - -/* ======================== FAL Flash 设备定义 ======================== */ - -/* GD5F2GQ5UE FAL 设备实例,总容?56MB,块大小128KB */ -const struct fal_flash_dev g_gd5f2gq5ue_flash = { - .name = "gd5f2gq5ue", - .addr = 0, - .len = GD5F_TOTAL_SIZE, - .blk_size = GD5F_BLOCK_SIZE, - .ops = { - .init = gd5f_fal_init, - .read = gd5f_fal_read, - .write = gd5f_fal_write, - .erase = gd5f_fal_erase, - }, - .write_gran = 8, -}; - diff --git a/Drivers/BSP/GD5F2GQ5UE/fdb_cfg.h b/Drivers/BSP/GD5F2GQ5UE/fdb_cfg.h deleted file mode 100644 index 62075b5..0000000 --- a/Drivers/BSP/GD5F2GQ5UE/fdb_cfg.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef __FDB_CFG_H -#define __FDB_CFG_H - -/* - * 模块名称:FlashDB 配置 - * 模块功能:配置 FlashDB 数据库功能开关和参数 - * 适用平台:STM32F407ZGT6 - * 作者:王建锋 - * 创建日期:2026-07-16 - * 修改记录: - * 2026-07-16 王建锋 创建初始版本 - */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* 启用 KVDB(键值数据库) */ -#define FDB_USING_KVDB - -/* KVDB 版本号变化时自动更新到最新默认值(默认关闭) */ -/* #define FDB_KV_AUTO_UPDATE */ - -/* 启用 TSDB(时序数据库) */ -#define FDB_USING_TSDB - -/* 使用 FAL 存储模式(非文件模式) */ -#define FDB_USING_FAL_MODE - -/* Flash 写入粒度,单位:bit,STM32F4 字节可编程 = 8 */ -#define FDB_WRITE_GRAN 8 - -/* 调试输出使能 */ -/*#define FDB_DEBUG_ENABLE*/ - -#ifdef __cplusplus -} -#endif - -#endif /* __FDB_CFG_H */ diff --git a/Drivers/BSP/GD5F2GQ5UE/nand_ftl.c b/Drivers/BSP/GD5F2GQ5UE/nand_ftl.c index aad373c..d7b5a6c 100644 --- a/Drivers/BSP/GD5F2GQ5UE/nand_ftl.c +++ b/Drivers/BSP/GD5F2GQ5UE/nand_ftl.c @@ -16,8 +16,8 @@ #include "nand.h" #include "map.h" -/* 统一分区配置 */ -#include "fal_cfg.h" +/* FTL 分区起始地址(块 1024,偏移 128MB) */ +#define FTL_FATFS_OFFSET (128U * 1024U * 1024U) /* 调试输出配置 */ #define DBG_TAG "[NAND_FTL]" diff --git a/Lib/FlashDB b/Lib/FlashDB deleted file mode 160000 index 8236571..0000000 --- a/Lib/FlashDB +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8236571f6e29273a16bba62061bf0405e4186878 diff --git a/MDK-ARM/STM32F407-Demo.uvprojx b/MDK-ARM/STM32F407-Demo.uvprojx index 765829b..cb157e4 100644 --- a/MDK-ARM/STM32F407-Demo.uvprojx +++ b/MDK-ARM/STM32F407-Demo.uvprojx @@ -340,7 +340,7 @@ USE_HAL_DRIVER,STM32F407xx,NDEBUG - ../Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include;../Drivers/BSP;../Drivers/BSP/CH395F;../Drivers/BSP/GD5F2GQ5UE;../Lib/FlashDB/port/fal/inc;../Lib/FlashDB/inc;../Drivers/BSP/TPAFE5160;../Drivers/BSP/SD2506;../Drivers/BSP/RS485;../Drivers/BSP/NET;../App;../App/task;../App/util;../Middlewares/Third_Party/FreeRTOS/Source/include;../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2;../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F;../Lib/dhara;../Lib/FatFs + ../Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include;../Drivers/BSP;../Drivers/BSP/CH395F;../Drivers/BSP/GD5F2GQ5UE;../Drivers/BSP/TPAFE5160;../Drivers/BSP/SD2506;../Drivers/BSP/RS485;../Drivers/BSP/NET;../App;../App/task;../App/util;../Middlewares/Third_Party/FreeRTOS/Source/include;../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2;../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F;../Lib/dhara;../Lib/FatFs @@ -1221,11 +1221,6 @@ 1 ..\Drivers\BSP\CH395F\ch395f_test.c - - fal_flash_gd5f2gq5ue.c - 1 - ..\Drivers\BSP\GD5F2GQ5UE\fal_flash_gd5f2gq5ue.c - gd5f2gq5ue.c 1 @@ -1263,46 +1258,6 @@ - - lib/FlashDB - - - fdb.c - 1 - ..\Lib\FlashDB\src\fdb.c - - - fdb_kvdb.c - 1 - ..\Lib\FlashDB\src\fdb_kvdb.c - - - fdb_tsdb.c - 1 - ..\Lib\FlashDB\src\fdb_tsdb.c - - - fdb_utils.c - 1 - ..\Lib\FlashDB\src\fdb_utils.c - - - fal.c - 1 - ..\Lib\FlashDB\port\fal\src\fal.c - - - fal_flash.c - 1 - ..\Lib\FlashDB\port\fal\src\fal_flash.c - - - fal_partition.c - 1 - ..\Lib\FlashDB\port\fal\src\fal_partition.c - - - Middlewares/FreeRTOS diff --git a/MDK-ARM/build_log.txt b/MDK-ARM/build_log.txt index 200ee90..0c5221c 100644 --- a/MDK-ARM/build_log.txt +++ b/MDK-ARM/build_log.txt @@ -3,73 +3,65 @@ Rebuild target 'STM32F407-Demo' assembling startup_stm32f407xx.s... compiling crc.c... compiling ringbuf.c... +compiling dma.c... +compiling stm32f4xx_hal_timebase_tim.c... +compiling stm32f4xx_it.c... +compiling spi.c... +compiling stm32f4xx_hal_flash_ramfunc.c... compiling i2c.c... compiling gpio.c... -compiling stm32f4xx_hal_msp.c... -compiling spi.c... -compiling stm32f4xx_it.c... -compiling stm32f4xx_hal_timebase_tim.c... -compiling sys_clock.c... -compiling stm32f4xx_hal_flash_ex.c... -compiling dma.c... -compiling app_main.c... -compiling stm32f4xx_hal_flash_ramfunc.c... -compiling stm32f4xx_hal_flash.c... -compiling usart.c... -compiling stm32f4xx_hal_gpio.c... compiling stm32f4xx_hal_rcc_ex.c... -compiling rs485_task.c... +compiling app_main.c... +compiling stm32f4xx_hal_msp.c... +compiling stm32f4xx_hal_gpio.c... +compiling stm32f4xx_hal_flash_ex.c... +compiling stm32f4xx_hal_flash.c... +compiling sys_clock.c... +compiling usart.c... compiling adc_task.c... -compiling stm32f4xx_hal_rcc.c... -compiling net_task.c... -compiling freertos.c... -compiling main.c... +compiling rs485_task.c... compiling stm32f4xx_hal_tim_ex.c... +compiling net_task.c... +compiling stm32f4xx_hal_rcc.c... +compiling main.c... +compiling freertos.c... compiling stm32f4xx_hal_tim.c... -compiling fdb.c... -compiling fdb_kvdb.c... -compiling fdb_tsdb.c... -compiling fdb_utils.c... -compiling fal.c... -compiling fal_flash.c... -compiling fal_partition.c... +compiling croutine.c... +compiling event_groups.c... +compiling list.c... +compiling queue.c... +compiling stream_buffer.c... +compiling timers.c... +compiling tasks.c... +compiling heap_4.c... +compiling port.c... compiling stm32f4xx_hal_dma_ex.c... compiling stm32f4xx_hal_dma.c... -compiling croutine.c... -compiling stm32f4xx_hal_pwr_ex.c... -compiling stm32f4xx_hal_i2c_ex.c... compiling stm32f4xx_hal_pwr.c... -compiling stm32f4xx_hal.c... -compiling event_groups.c... -compiling system_stm32f4xx.c... -compiling stm32f4xx_hal_exti.c... +compiling journal.c... +compiling stm32f4xx_hal_pwr_ex.c... +compiling map.c... compiling stm32f4xx_hal_cortex.c... -compiling list.c... +compiling stm32f4xx_hal.c... +compiling system_stm32f4xx.c... +compiling stm32f4xx_hal_i2c_ex.c... +compiling stm32f4xx_hal_exti.c... +compiling ff.c... compiling rs485.c... -compiling fal_flash_gd5f2gq5ue.c... compiling tpafe5160.c... compiling sd2506.c... -compiling stm32f4xx_hal_spi.c... -compiling ch395f.c... compiling gd5f2gq5ue.c... -compiling queue.c... -compiling nand_ftl.c... -compiling stream_buffer.c... +compiling ch395f.c... +compiling stm32f4xx_hal_spi.c... compiling stm32f4xx_hal_uart.c... compiling net_select.c... +compiling nand_ftl.c... compiling ch395f_test.c... -compiling timers.c... compiling net_socket.c... -compiling heap_4.c... -compiling tasks.c... compiling stm32f4xx_hal_i2c.c... -compiling map.c... -compiling journal.c... -compiling port.c... -compiling ff.c... compiling cmsis_os2.c... linking... -Program Size: Code=58900 RO-data=3560 RW-data=244 ZI-data=54796 +Program Size: Code=48264 RO-data=1416 RW-data=220 ZI-data=53788 FromELF: creating hex file... ".\STM32F407-Demo\STM32F407-Demo.axf" - 0 Error(s), 0 Warning(s). -Build Time Elapsed: 00:00:20 +Build Time Elapsed: 00:00:16 diff --git a/Src/freertos.c b/Src/freertos.c index fc85fb6..2541a18 100644 --- a/Src/freertos.c +++ b/Src/freertos.c @@ -32,7 +32,6 @@ #include "net_socket.h" #include "usart.h" #include "ff.h" -#include "flashdb.h" #include "gd5f2gq5ue.h" /* USER CODE END Includes */ @@ -76,7 +75,6 @@ typedef struct { /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN Variables */ -static struct fdb_kvdb s_kvdb; static storage_test_stats_t g_storage_stats; static uint8_t s_perf_buf[4096]; /* USER CODE END Variables */ @@ -173,7 +171,6 @@ void StartDefaultTask(void *argument) static uint8_t work[FF_MAX_SS]; char read_buf[64]; const char *test_str = "Hello FatFS + dhara FTL!"; - fdb_err_t fdb_ret; memset(&g_storage_stats, 0, sizeof(g_storage_stats)); @@ -211,44 +208,6 @@ void StartDefaultTask(void *argument) f_unlink("test.txt"); } - /* ==================== FlashDB KVDB 测试 ==================== */ - - DBG_INFO("=== Storage Test: FlashDB KVDB ==="); - - /* 第一次 init(会触发 FAL 初始化,报告错误但成功) */ - fdb_ret = fdb_kvdb_init(&s_kvdb, "kvdb1", "fdb_kvdb1", NULL, NULL); - - /* 清除旧验证数据:格式化所有 sector */ - fdb_kv_set_default(&s_kvdb); - /* 重新初始化干净的数据库 */ - fdb_ret = fdb_kvdb_init(&s_kvdb, "kvdb1", "fdb_kvdb1", NULL, NULL); - STORAGE_TEST_CHECK(fdb_ret == FDB_NO_ERR, "fdb_kvdb_init"); - - if (fdb_ret == FDB_NO_ERR) { - fdb_ret = fdb_kv_set(&s_kvdb, "hello", "FlashDB KVDB!"); - STORAGE_TEST_CHECK(fdb_ret == FDB_NO_ERR, "fdb_kv_set(hello)"); - - char *val = fdb_kv_get(&s_kvdb, "hello"); - STORAGE_TEST_CHECK(val != NULL && strcmp(val, "FlashDB KVDB!") == 0, - "fdb_kv_get(hello) -> \"%s\"", val ? val : "NULL"); - - uint32_t blob_data = 0xDEADBEEF; - struct fdb_blob blob; - fdb_blob_make(&blob, &blob_data, sizeof(blob_data)); - fdb_ret = fdb_kv_set_blob(&s_kvdb, "counter", &blob); - STORAGE_TEST_CHECK(fdb_ret == FDB_NO_ERR, "fdb_kv_set_blob(counter)"); - - uint32_t read_data = 0; - struct fdb_blob read_blob; - fdb_blob_make(&read_blob, &read_data, sizeof(read_data)); - size_t len = fdb_kv_get_blob(&s_kvdb, "counter", &read_blob); - STORAGE_TEST_CHECK(len == sizeof(read_data) && read_data == 0xDEADBEEF, - "fdb_kv_get_blob(counter) -> 0x%08lX", (unsigned long)read_data); - - fdb_kv_del(&s_kvdb, "hello"); - fdb_kv_del(&s_kvdb, "counter"); - } - /* ==================== FTL + FatFS 性能测试 ==================== */ DBG_INFO("=== Storage Test: Performance ==="); diff --git a/docs/FlashDB使用说明.md b/docs/FlashDB使用说明.md deleted file mode 100644 index 989c6c8..0000000 --- a/docs/FlashDB使用说明.md +++ /dev/null @@ -1,400 +0,0 @@ -# FlashDB 使用说明 - -## 1. 概述 - -本项目使用 [FlashDB](https://github.com/armink/FlashDB) 嵌入式数据库,提供两种数据库: - -- **KVDB**(键值数据库):存储键值对,类似 Redis 简化版 -- **TSDB**(时序数据库):存储带时间戳的日志记录,支持按时间范围查询 - -底层存储介质为 GD5F2GQ5UE SPI NAND Flash(256MB),通过 FAL(Flash Abstraction Layer)抽象层访问。 - -## 2. 软件架构 - -``` -┌─────────────────────────────────────────┐ -│ 用户应用(main.c) │ -├──────────────┬──────────────────────────┤ -│ fdb_kvdb │ fdb_tsdb │ -│ (键值数据库) │ (时序数据库) │ -├──────────────┴──────────────────────────┤ -│ FlashDB 核心 │ -│ Lib/FlashDB/src/ │ -├─────────────────────────────────────────┤ -│ FAL 抽象层 │ -│ Lib/FlashDB/port/fal/src/ │ -├─────────────────────────────────────────┤ -│ FAL 设备适配层 │ -│ fal_flash_gd5f2gq5ue.c │ -├─────────────────────────────────────────┤ -│ GD5F2GQ5UE SPI NAND 驱动 │ -│ gd5f2gq5ue.c │ -├─────────────────────────────────────────┤ -│ SPI1 硬件外设 + HAL 驱动 │ -└─────────────────────────────────────────┘ -``` - -## 3. 文件清单 - -| 文件 | 说明 | 是否自编 | -|------|------|----------| -| `Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h` | NAND 驱动头文件 | 是 | -| `Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c` | NAND 驱动实现 | 是 | -| `Drivers/BSP/GD5F2GQ5UE/fal_flash_gd5f2gq5ue.c` | FAL 设备适配 | 是 | -| `Drivers/BSP/GD5F2GQ5UE/fal_cfg.h` | FAL 设备表 + 分区表 | 是 | -| `Drivers/BSP/GD5F2GQ5UE/fdb_cfg.h` | FlashDB 功能配置 | 是 | -| `Lib/FlashDB/src/` | FlashDB 核心源码 | 否 | -| `Lib/FlashDB/port/fal/src/` | FAL 硬件抽象框架源码 | 否 | - -## 4. 硬件配置 - -### 4.1 Flash 芯片参数 - -| 参数 | 值 | -|------|-----| -| 型号 | GD5F2GQ5UE(GigaDevice) | -| 总容量 | 2Gbit = 256MB | -| 页大小 | 2048 字节 | -| Spare 区 | 64 字节 | -| 每块页数 | 64 页 | -| 块大小 | 128KB(64 × 2048) | -| 总块数 | 2048 | -| SPI 模式 | Mode 0(CPOL=0, CPHA=0) | -| SPI 时钟 | 42MHz(APB2=84MHz, 分频=2) | -| MID | 0xC8 | -| DID | 0x52 | - -### 4.2 引脚连接 - -| 信号 | STM32 引脚 | 方向 | 说明 | -|------|-----------|------|------| -| CS# | PE0 | OUT | 片选,低有效 | -| SCLK | PB3 | OUT | SPI1 时钟 | -| MOSI | PB5 | OUT | SPI1 主出从入 | -| MISO | PB4 | IN | SPI1 主入从出 | -| WP# | PB8 | OUT | 写保护,低有效(拉高禁用) | -| HOLD# | PE1 | OUT | 保持,低有效(拉高禁用) | - -### 4.3 GPIO 初始化 - -CubeMX 中需确保以下 GPIO 上电默认电平: - -- **CS#** (PE0):上电输出 **高电平**(未选中) -- **HOLD#** (PE1):上电输出 **高电平**(不保持) -- **WP#** (PB8):上电输出 **高电平**(不禁用写保护) - -> 若 GPIO 初始电平错误,SPI 通信将完全无响应。 - -## 5. 分区规划 - -| 分区名 | 设备 | 偏移 | 大小 | 用途 | -|--------|------|------|------|------| -| fdb_kvdb1 | gd5f2gq5ue | 0 | 64MB | KVDB 键值数据库 | -| fdb_tsdb1 | gd5f2gq5ue | 64MB | 64MB | TSDB 时序数据库 | -| (未分配) | - | 128MB | 128MB | 剩余空间 | - -共使用 128MB / 256MB,剩余 128MB 可扩展。 - -## 6. 初始化流程 - -``` -1. HAL_Init() -2. SystemClock_Config() -3. MX_GPIO_Init() ← CS#/HOLD#/WP# 初始电平 -4. MX_USART1_UART_Init() ← 调试串口 -5. MX_SPI2_Init() ← CH395F 以太网 -6. MX_SPI1_Init() ← GD5F2GQ5UE NAND -7. gd5f2gq5ue_init() ← NAND 初始化 -8. fdb_kvdb_init() ← FlashDB KVDB 初始化 -``` - -### 6.1 gd5f2gq5ue_init() 内部步骤 - -``` -1. CS#/WP#/HOLD# 拉高 -2. 发送复位命令(FFh),等待 5ms -3. 读取芯片 ID(9Fh),校验 MID=0xC8, DID=0x52 -4. 使能内部 ECC:SET_FEATURE(B0h, 10h) -5. 解除块保护:SET_FEATURE(A0h, 00h) -``` - -> **关键点**:SET_FEATURE 命令前必须先发写使能(06h),否则设置不生效。 - -## 7. KVDB 使用方法 - -### 7.1 初始化 - -```c -#include "flashdb.h" - -static struct fdb_kvdb kvdb; - -/* path 参数对应分区表中的分区名 "fdb_kvdb1" */ -/* default_kv 传 NULL 表示不使用默认键值 */ -int ret = fdb_kvdb_init(&kvdb, "db", "fdb_kvdb1", NULL, NULL); -if (ret != FDB_NO_ERR) { - /* 初始化失败处理 */ -} -``` - -### 7.2 字符串读写 - -```c -/* 写入字符串 */ -fdb_kv_set(&kvdb, "device_name", "STM32F407-DTU"); - -/* 读取字符串(返回内部缓存指针,下次写入同一 key 后失效) */ -char *val = fdb_kv_get(&kvdb, "device_name"); -if (val) { - printf("device_name = %s\n", val); -} -``` - -### 7.3 二进制数据读写(Blob) - -```c -#include - -/* 写入二进制数据 */ -uint32_t temp = 2560; -fdb_kv_set_blob(&kvdb, "temperature", - fdb_blob_make(NULL, &temp, sizeof(temp))); - -/* 读取二进制数据 */ -uint32_t read_temp = 0; -fdb_kv_get_blob(&kvdb, "temperature", - fdb_blob_make(NULL, &read_temp, sizeof(read_temp))); -printf("temperature = %u\n", read_temp); -``` - -### 7.4 删除键 - -```c -fdb_kv_del(&kvdb, "device_name"); -``` - -### 7.5 遍历所有键 - -```c -struct fdb_kv kv; -struct fdb_kv_iterator itr; - -fdb_kv_iterator_init(&kvdb, &itr); -while (fdb_kv_iterate(&kvdb, &itr)) { - kv = itr.curr; - printf("key: %s\n", kv.name); -} -``` - -### 7.6 打印所有键值 - -```c -fdb_kv_print(&kvdb); -``` - -## 8. TSDB 使用方法 - -### 8.1 获取时间戳 - -FlashDB 需要用户提供时间戳获取函数。本项目使用 HAL_GetTick()(毫秒): - -```c -static fdb_time_t get_time(void) -{ - return (fdb_time_t)HAL_GetTick(); -} -``` - -### 8.2 初始化 - -```c -static struct fdb_tsdb tsdb; - -/* max_len 参数限制单条记录最大长度 */ -int ret = fdb_tsdb_init(&tsdb, "tsdb", "fdb_tsdb1", - get_time, 256, NULL); -``` - -### 8.3 追加记录 - -```c -/* 写入二进制数据,自动附加当前时间戳 */ -uint32_t sensor_val = 3200; -fdb_tsl_append(&tsdb, - fdb_blob_make(NULL, &sensor_val, sizeof(sensor_val))); -``` - -### 8.4 遍历记录 - -```c -/* 正序遍历 */ -fdb_tsl_iter(&tsdb, tsl_cb_func, NULL); - -/* 逆序遍历 */ -fdb_tsl_iter_reverse(&tsdb, tsl_cb_func, NULL); - -/* 按时间范围遍历 */ -fdb_tsl_iter_by_time(&tsdb, from_time, to_time, tsl_cb_func, NULL); -``` - -回调函数原型: - -```c -static void tsl_cb_func(struct fdb_tsl *tsl, void *arg) -{ - struct fdb_blob blob; - uint32_t val; - - /* 读取数据 */ - fdb_blob_read((fdb_db_t)&tsl, - fdb_tsl_to_blob(tsl, fdb_blob_make(&blob, &val, sizeof(val)))); - printf("ts=%lu, val=%lu\n", tsl->time, val); -} -``` - -### 8.5 查询记录数量 - -```c -size_t count = fdb_tsl_query_count(&tsdb, from_time, to_time, - FDB_TSL_STATUS_APPEND); -``` - -### 8.6 清理所有记录 - -```c -fdb_tsl_clean(&tsdb); -``` - -## 9. 配置文件说明 - -### 9.1 fdb_cfg.h - -| 宏 | 说明 | -|----|------| -| `FDB_USING_KVDB` | 启用 KVDB | -| `FDB_USING_TSDB` | 启用 TSDB | -| `FDB_USING_FAL_MODE` | 使用 FAL 模式(非文件系统) | -| `FDB_WRITE_GRAN` | 写入粒度 8(字节可编程) | -| `FDB_DEBUG_ENABLE` | 启用调试输出 | -| `FDB_KV_AUTO_UPDATE` | KVDB 版本变化时自动更新(默认关闭) | - -### 9.2 fal_cfg.h - -分区表定义,修改分区大小需同时调整偏移和大小: - -```c -#define FAL_PART_TABLE \ -{ \ - {FAL_PART_MAGIC_WORD, "fdb_kvdb1", "gd5f2gq5ue", 0, 64*1024*1024, 0}, \ - {FAL_PART_MAGIC_WORD, "fdb_tsdb1", "gd5f2gq5ue", 64*1024*1024, 64*1024*1024, 0}, \ -} -``` - -字段顺序:`{魔数, 分区名, 设备名, 偏移, 大小, 标志}` - -## 10. Keil 工程配置 - -### 10.1 头文件搜索路径 - -在 Keil 工程 Options → C/C++ → Include Paths 中添加: - -``` -../Drivers/BSP/GD5F2GQ5UE -../Lib/FlashDB/inc -../Lib/FlashDB/port/fal/inc -``` - -### 10.2 编译的源文件 - -需在 Keil 工程中添加以下源文件: - -``` -Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c -Drivers/BSP/GD5F2GQ5UE/fal_flash_gd5f2gq5ue.c -Lib/FlashDB/src/fdb.c -Lib/FlashDB/src/fdb_kvdb.c -Lib/FlashDB/src/fdb_tsdb.c -Lib/FlashDB/src/fdb_utils.c -Lib/FlashDB/port/fal/src/fal.c -Lib/FlashDB/port/fal/src/fal_flash.c -Lib/FlashDB/port/fal/src/fal_partition.c -``` - -### 10.3 全局宏定义 - -确保工程中定义了: - -``` -USE_HAL_DRIVER, STM32F407xx -``` - -## 11. 注意事项 - -### 11.1 NAND Flash 特性 - -1. **写前必须擦除**:NAND 只能将 1→0,不能 0→1。写入前目标块必须先擦除(全部变为 0xFF) -2. **擦除单位是块**:最小擦除单位 128KB,不能按页擦除 -3. **写入单位是页**:单次写入不超过一页(2048 字节),跨页需驱动层拆分 -4. **Spare 区不可直接访问**:驱动已使能内部 ECC,Spare 区由芯片硬件管理 - -### 11.2 驱动层注意事项 - -1. **每次 SPI 事务前**:必须 `CS_LOW()` 拉低片选 -2. **每次 SPI 事务后**:必须 `CS_HIGH()` 拉高片选 -3. **SET_FEATURE 前必须写使能**:先发 06h,再发 1Fh + 地址 + 数据 -4. **块擦除地址是字节地址**:D8h 命令的参数 = 块编号 × 128KB(不是块编号本身) -5. **读取 ID 需跳过 dummy 字节**:9Fh 返回 3 字节,第 0 字节无意义,第 1 字节 MID,第 2 字节 DID - -### 11.3 FlashDB 使用注意事项 - -1. **fdb_kv_get 返回值是内部缓存**:下次对同一 key 写入后,之前返回的指针失效 -2. **TSDB 需要用户提供时间戳**:通过 `get_time` 回调,本项目使用 `HAL_GetTick()` -3. **fdb_kvdb_init 的 path 参数**:对应分区表中的分区名 `"fdb_kvdb1"` -4. **FlashDB 开启 FDB_DEBUG_ENABLE 后**:会通过 `fdb_print()` 输出调试信息,需确保有可用的输出(如 printf 重定向到串口) -5. **分区大小修改后**:需同步更新 `fal_cfg.h` 中的偏移和大小 - -### 11.4 常见问题 - -| 现象 | 可能原因 | 解决方法 | -|------|----------|----------| -| init 返回 -6 (ID_MISMATCH) | SPI 通信失败或芯片未上电 | 检查接线、GPIO 初始电平、虚焊 | -| KVDB init 失败 | 分区名不匹配 | 确认 `fdb_kvdb_init` 的 path 与 `fal_cfg.h` 一致 | -| 写入后读取为空 | 未擦除或写入失败 | 检查写入返回值,确认目标块已擦除 | -| 读取数据异常 | ECC 错误 | 检查 `gd5f2gq5ue_init` 是否成功使能 ECC | -| SET_FEATURE 未生效 | 缺少写使能命令 | 确认 `gd5f_set_feature` 中先调用 `gd5f_write_enable()` | - -## 12. 调试方法 - -### 12.1 串口调试输出 - -FlashDB 调试输出通过 `fdb_print` 宏实现。在 `fdb_cfg.h` 中定义 `FDB_DEBUG_ENABLE` 后,FlashDB 内部操作会自动输出到标准输出。 - -确保 Keil 工程中 `printf` 已重定向到 USART1(PA9/PA10, 115200bps)。 - -### 12.2 NAND 驱动调试 - -可通过串口输出以下信息验证驱动工作正常: - -```c -/* 读取芯片 ID */ -uint8_t mid, did; -gd5f2gq5ue_read_id(&mid, &did); -printf("MID=0x%02X DID=0x%02X\n", mid, did); -/* 预期输出:MID=0xC8 DID=0x52 */ - -/* 初始化测试 */ -int ret = gd5f2gq5ue_init(); -printf("init ret=%d\n", ret); -/* 预期输出:init ret=0 */ -``` - -### 12.3 FAL 设备注册验证 - -```c -#include "fal.h" - -/* 检查 FAL 是否初始化成功 */ -int ret = fal_init(); -printf("fal_init ret=%d\n", ret); -/* 预期输出:fal_init ret=0 */ -``` diff --git a/docs/STM32F4-Base存储架构说明.md b/docs/STM32F4-Base存储架构说明.md index 34bd428..807f8ff 100644 --- a/docs/STM32F4-Base存储架构说明.md +++ b/docs/STM32F4-Base存储架构说明.md @@ -2,28 +2,24 @@ ## 1. 概述 -本项目在 GD5F2GQ5UE SPI NAND Flash(256MB)上实现了四层存储软件栈: +本 项目在 GD5F2GQ5UE SPI NAND Flash(256MB)上实现了三层存储软件栈: ``` ┌─────────────────────────────────────────────────────────────┐ │ 应用程序 (main, freertos) │ -├──────────────────────┬──────────────────┬──────────────────┤ -│ │ │ │ -│ FlashDB KVDB │ FlashDB TSDB │ FatFs │ -│ (键值数据库) │ (时序数据库) │ (文件系统) │ -│ │ │ │ -├──────────┬───────────┴──────┬───────────┴──────────────────┤ -│ │ │ │ -│ FAL 抽象层 (分区访问) │ dhara FTL │ -│ (Flash Abstraction Layer)│ (地址映射 · 磨损均衡 │ -│ 直接转发到底层驱动) │ 坏块管理 · 垃圾回收) │ -│ │ │ │ -├──────────┴──────────────────┴──────────────────────────────┤ -│ GD5F2GQ5UE NAND Flash 驱动 (底层 SPI) │ -│ 硬件 SPI · 页读写 · 块擦除 · BBT · 内部 ECC 使能 │ ├─────────────────────────────────────────────────────────────┤ -│ SPI1 硬件外设 (PB3 SCK, PB4 MISO, PB5 MOSI) │ -│ 42MHz · Mode 0 · MSB First · DMA2 (S0-RX, S3-TX) │ +│ │ +│ FatFs (文件系统) │ +│ │ +├─────────────────────────────────────────────────────────────┤ +│ dhara FTL │ +│ (地址映射 · 磨损均衡 · 坏块管理 · 垃圾回收) │ +├─────────────────────────────────────────────────────────────┤ +│ GD5F2GQ5UE NAND Flash 驱动 (底层 SPI) │ +│ 硬件 SPI · 页读写 · 块擦除 · BBT · 内部 ECC 使能 │ +├─────────────────────────────────────────────────────────────┤ +│ SPI1 硬件外设 (PB3 SCK, PB4 MISO, PB5 MOSI) │ +│ 42MHz · Mode 0 · MSB First · DMA2 (S0-RX, S3-TX) │ │ 小包轮询(≤32B) · 页数据 DMA (>32B) │ └─────────────────────────────────────────────────────────────┘ ``` @@ -32,20 +28,17 @@ ┌─────────────────────────────────────────────────────────────┐ │ 物理分区布局 (256MB) │ │ │ -│ ┌──────────────────────┬──────────────────┬───────────────┐ │ -│ │ fdb_kvdb1 (64MB) │ fdb_tsdb1 (64MB) │ ftl_fatfs │ │ -│ │ Block 0~511 │ Block 512~1023 │ Block 1024~2047│ │ -│ │ FlashDB 键值数据库 │ FlashDB 时序数据库│ dhara + FatFS │ │ -│ └──────────────────────┴──────────────────┴───────────────┘ │ -│ 偏移: 0 64MB 128MB 256MB│ +│ ┌─────────────────────────────────────┬───────────────────┐ │ +│ │ 预留 (128MB) │ ftl_fatfs (128MB) │ │ +│ │ Block 0~1023 │ Block 1024~2047 │ │ +│ │ 未使用 │ dhara FTL + FatFS │ │ +│ └─────────────────────────────────────┴───────────────────┘ │ +│ 偏移: 0 128MB 256MB │ └─────────────────────────────────────────────────────────────┘ ``` -**两条独立路径:** -- **FlashDB 路径**:`FlashDB → FAL → gd5f2gq5ue 驱动`,FAL 是薄封装层,将 FAL 读写请求直接转发给底层 NAND 驱动。FlashDB 在 FAL 之上自行管理磨损均衡和掉电安全。 -- **FatFS 路径**:`FatFS → dhara FTL → gd5f2gq5ue 驱动`,FTL 提供 LBA 到物理页的映射、磨损均衡、垃圾回收和坏块管理,FatFS 通过标准 `disk_*` 接口访问 FTL 提供的块设备。 - -两个路径共享最底层 NAND 驱动,但各自管理不同的物理分区(FlashDB 管理 Block 0~1023,FTL 管理 Block 1024~2047),互不干扰。 +**数据路径:** +- **应用** → `FatFS` → `dhara FTL` → `gd5f2gq5ue 驱动`。FTL 提供 LBA 到物理页的映射、磨损均衡、坏块管理和垃圾回收,FatFS 通过标准 `disk_*` 接口访问 FTL 提供的块设备。 **初始化顺序:** ``` @@ -53,11 +46,8 @@ HAL_Init → SystemClock_Config → MX_GPIO_Init → MX_USART1_UART_Init → MX_SPI2_Init → MX_SPI1_Init → gd5f2gq5ue_init() // NAND 底层驱动 (含 BBT 扫描 + ECC 使能) → app_main_init() // 应用层初始化 - ├─ FlashDB: fdb_kvdb_init() // KVDB (可选) - ├─ FlashDB: fdb_tsdb_init() // TSDB (可选) - └─ f_mount() // 触发 FTL 初始化和 FatFS 挂载 → osKernelStart() // FreeRTOS 启动 - ├─ defaultTask → 存储测试 + 业务 + ├─ defaultTask → f_mount() → 存储测试 + 业务 ├─ netTask → 网络协议栈轮询 ├─ adcTask → ADC 采集 └─ rs485Task → RS485 通信 @@ -98,34 +88,26 @@ HAL_Init → SystemClock_Config → MX_GPIO_Init → MX_USART1_UART_Init ## 3. 分区布局 -三个分区物理隔离、互不重叠,配置集中在 `Drivers/BSP/GD5F2GQ5UE/fal_cfg.h:18-30`: +单个分区,配置在 `Drivers/BSP/GD5F2GQ5UE/nand_ftl.c`: ```c -#define FDB_KVDB1_OFFSET 0 -#define FDB_KVDB1_SIZE (64 * 1024 * 1024) // 64MB -#define FDB_TSDB1_OFFSET (FDB_KVDB1_OFFSET + FDB_KVDB1_SIZE) -#define FDB_TSDB1_SIZE (64 * 1024 * 1024) // 64MB -#define FTL_FATFS_OFFSET (FDB_TSDB1_OFFSET + FDB_TSDB1_SIZE) // 128MB -#define FTL_FATFS_SIZE (128 * 1024 * 1024) // 128MB +#define FTL_FATFS_OFFSET (128U * 1024U * 1024U) // 128MB +#define FTL_FATFS_SIZE (128 * 1024 * 1024) // 128MB ``` ### 3.1 分区对照表 | 分区名 | 偏移 | 大小 | 物理块范围 | 逻辑用途 | |--------|------|------|-----------|----------| -| `fdb_kvdb1` | 0 | 64 MB | Block 0~511 | FlashDB 键值数据库 (KVDB) | -| `fdb_tsdb1` | 64 MB | 64 MB | Block 512~1023 | FlashDB 时序数据库 (TSDB) | +| 预留 | 0 | 128 MB | Block 0~1023 | 未使用 | | `ftl_fatfs` | 128 MB | 128 MB | Block 1024~2047 | dhara FTL + FatFS | ### 3.2 配置联动 -所有分区边界在 `fal_cfg.h` 定义后,自动传播到各子模块: - -- **FAL 分区表** — `FAL_PART_TABLE` 宏直接引用 `FDB_KVDB1_OFFSET/SIZE`、`FDB_TSDB1_OFFSET/SIZE` -- **FTL** — `nand_ftl.c:29` 通过 `#define FTL_START_BLOCK (FTL_FATFS_OFFSET / GD5F_BLOCK_SIZE)` 自动计算起始块号(当前 = 1024),`FTL_NUM_BLOCKS` 自动适配剩余块数 +- **FTL** — `nand_ftl.c` 中 `FTL_START_BLOCK = FTL_FATFS_OFFSET / GD5F_BLOCK_SIZE = 1024`,`FTL_NUM_BLOCKS` 自动适配剩余块数 - **FatFS** — 通过 `disk_ioctl(GET_SECTOR_COUNT)` 获取 FTL 管理的扇区数 -> 调整分区大小时只需修改 `fal_cfg.h` 顶部 6 个宏,所有下游模块自动适配。 +> 调整分区大小时只需修改 `nand_ftl.c` 中的 `FTL_FATFS_OFFSET` 宏,下游模块自动适配。 --- @@ -237,94 +219,9 @@ DMA 消除了轮询模式下 SPI 状态寄存器查检的逐字节 CPU 开销, --- -## 5. FAL 抽象层 +## 5. dhara FTL (Flash Translation Layer) -FAL (Flash Abstraction Layer) 是 FlashDB 自带的 flash 抽象层,**仅 FlashDB 路径使用**。它是一个薄封装层,将 FAL 的 read/write/erase 请求直接转发给底层 NAND 驱动,不做地址映射或磨损均衡(这些由 FlashDB 自身在 FAL 之上完成)。 - -FAL 不参与 FatFS/FTL 路径。FTL 有自己的 HAL 回调直接对接底层 NAND 驱动,与 FAL 无关。 - -``` -FlashDB ──→ FAL ──→ gd5f2gq5ue_read/write/erase (直接透传) -FatFs ──→ dhara FTL ──→ dhara_nand_* 回调 ──→ gd5f2gq5ue_* (独立路径) -``` - -### 5.1 设备注册 (fal_flash_gd5f2gq5ue.c) - -```c -const struct fal_flash_dev g_gd5f2gq5ue_flash = { - .name = "gd5f2gq5ue", - .addr = 0, - .len = GD5F_TOTAL_SIZE, // 256MB - .blk_size = GD5F_BLOCK_SIZE, // 128KB - .ops = { .init, .read, .write, .erase }, - .write_gran = 8, // byte programmable -}; -``` - -### 5.2 分区表 (fal_cfg.h) - -```c -#define FAL_PART_TABLE \ -{ \ - {FAL_PART_MAGIC_WORD, "fdb_kvdb1", "gd5f2gq5ue", FDB_KVDB1_OFFSET, FDB_KVDB1_SIZE, 0}, \ - {FAL_PART_MAGIC_WORD, "fdb_tsdb1", "gd5f2gq5ue", FDB_TSDB1_OFFSET, FDB_TSDB1_SIZE, 0}, \ -} -``` - -FlashDB 通过分区名 (`"fdb_kvdb1"`, `"fdb_tsdb1"`) 绑定到 FAL 分区。 - ---- - -## 6. FlashDB 数据库 - -### 6.1 配置 (fdb_cfg.h) - -```c -#define FDB_USING_KVDB // 启用键值数据库 -#define FDB_USING_TSDB // 启用时序数据库 -#define FDB_USING_FAL_MODE // 使用 FAL 存储模式 -#define FDB_WRITE_GRAN 8 // 写粒度 8bit (字节可编程) -``` - -### 6.2 查询接口 - -FlashDB 通过 FAL 分区名查找对应的分区设备,无需 FlashDB 驱动额外的设备注册。 - -#### 已知 Bug 修复:状态读取偏移 - -**问题**:`Lib/FlashDB/src/fdb_utils.c` 中 `_fdb_get_status()` 函数曾有一处错误的 off-by-one 修复(在第 130-139 行额外多减了一次 `status_num`),导致: -- 循环少检查最高状态位(只查 `byte[1,0]` 而非 `byte[2,1,0]`) -- `EMPTY`(状态 1)被错误地读成 `USING`(状态 2) -- 所有空扇区触发 KV 遍历,在全 `0xFF` 区域发现 `len=0xFFFFFFFF`,产生 `"The KV @0xXXXX0014 length has an error"` 报错 - -**修复**:2026-07-21 移除 `_fdb_get_status()` 中多余的 `status_num--`,恢复原始正确的循环边界。详见 `Lib/FlashDB/src/fdb_utils.c:126-144`。 - -### 6.3 KVDB 键值数据库 - -适用于存储配置参数、运行状态等少量键值对。 - -**特点:** -- 掉电安全 (写操作带 CRC 校验) -- 支持 blob (二进制数据块) -- 自动磨损均衡 -- 支持默认值 (首次启动自动写入) -- 支持 select/poll I/O 多路复用(`net_select.c`) - -### 6.4 TSDB 时序数据库 - -适用于存储采样数据、日志记录等时间序列数据。 - -**特点:** -- 固定长度记录 -- 时间戳索引 (需提供 `get_time` 回调) -- 自动擦除 (新数据覆盖最旧数据) -- 支持按时间范围查询 - ---- - -## 7. dhara FTL (Flash Translation Layer) - -### 7.1 概述 +### 5.1 概述 FTL 是 NAND Flash 上方最重要的组件,功能包括: @@ -336,7 +233,7 @@ FTL 是 NAND Flash 上方最重要的组件,功能包括: | **坏块管理** | 擦除/编程失败时自动跳过并标记坏块 | | **ECC 处理** | 检测和上报硬件 ECC 不可纠正错误 | -### 7.2 数据结构 +### 5.2 数据结构 ```c struct dhara_nand { @@ -350,7 +247,7 @@ struct dhara_map { }; ``` -### 7.3 NAND HAL (nand_ftl.c) +### 5.3 NAND HAL (nand_ftl.c) dhara 通过 7 个回调函数访问物理 NAND: @@ -366,7 +263,7 @@ dhara 通过 7 个回调函数访问物理 NAND: 所有回调自动将 dhara 逻辑块/页加 `FTL_START_BLOCK` 偏移转换为物理地址。 -### 7.4 初始化流程 (disk_initialize) +### 5.4 初始化流程 (disk_initialize) ``` 1. 设置 nand 参数 (log2_page_size=11, log2_ppb=6, num_blocks=1024) @@ -379,7 +276,7 @@ dhara 通过 7 个回调函数访问物理 NAND: 4. 页面缓存初始化 (s_cache_buf, s_cached_lpn, s_cache_dirty) ``` -### 7.5 页面缓存策略 +### 5.5 页面缓存策略 FTL 之上还有一个 **单页写回缓存 (write-back cache)**: @@ -391,9 +288,9 @@ FTL 之上还有一个 **单页写回缓存 (write-back cache)**: --- -## 8. FatFS 集成 +## 6. FatFS 集成 -### 8.1 配置 (ffconf.h) +### 6.1 配置 (ffconf.h) ```c #define FF_FS_READONLY 0 // 读写模式 @@ -405,7 +302,7 @@ FTL 之上还有一个 **单页写回缓存 (write-back cache)**: #define FF_FS_NORTC 1 // 无 RTC (固定时间戳) ``` -### 8.2 disk I/O 接口 +### 6.2 disk I/O 接口 | 函数 | 功能 | 关键实现 | |------|------|----------| @@ -415,7 +312,7 @@ FTL 之上还有一个 **单页写回缓存 (write-back cache)**: | `disk_write` | 写扇区 | 通过 FTL 映射写 (缓存优化) | | `disk_ioctl` | 控制命令 | GET_SECTOR_COUNT/SIZE/BLOCK_SIZE + CTRL_SYNC | -### 8.3 容量计算 +### 6.3 容量计算 ``` FTL 管理块数 = 1024 (Block 1024~2047) @@ -428,9 +325,9 @@ FTL 开销后 ≈ 93 MB (随 GC 和 journal 使用量波动) --- -## 9. 完整数据流 +## 7. 完整数据流 -### 9.1 写文件流程 +### 7.1 写文件流程 ``` f_write("hello.txt") @@ -450,7 +347,7 @@ f_close → disk_ioctl(CTRL_SYNC) └─ 写 journal 到 NAND (持久化映射表) ``` -### 9.2 f_mkfs 格式化流程 +### 7.2 f_mkfs 格式化流程 ``` f_mkfs("", &opts, work, size) @@ -463,9 +360,9 @@ f_mkfs("", &opts, work, size) --- -## 10. API 参考 +## 8. API 参考 -### 10.1 底层 NAND 驱动 (gd5f2gq5ue.h) +### 8.1 底层 NAND 驱动 (gd5f2gq5ue.h) | 函数 | 说明 | |------|------| @@ -495,31 +392,7 @@ f_mkfs("", &opts, work, size) | `gd5f_block_erase(block_addr)` | 块擦除 (D8h) | | `gd5f_check_ecc()` | 检查 ECC 状态位 | -### 10.2 FAL 接口 (via fal_flash_gd5f2gq5ue.c) - -| 函数 | 说明 | -|------|------| -| `g_gd5f2gq5ue_flash` | FAL 设备实例 | -| `fal_flash_device_find("gd5f2gq5ue")` | 查找 Flash 设备 | -| `fal_partition_find("fdb_kvdb1")` | 查找分区 | -| `fal_partition_read/write/erase` | 分区读写擦除 | - -### 10.3 FlashDB (via FlashDB 库) - -| 函数 | 说明 | -|------|------| -| `fdb_kvdb_init(&db, "kvdb1", "fdb_kvdb1", NULL, NULL)` | 初始化 KVDB | -| `fdb_kv_set(&db, "key", "value")` | 写键值 (字符串) | -| `fdb_kv_get(&db, "key")` | 读键值 (返回 char*) | -| `fdb_kv_del(&db, "key")` | 删除键值 | -| `fdb_kv_set_blob(&db, "key", &blob)` | 写二进制 blob | -| `fdb_kv_get_blob(&db, "key", &blob)` | 读二进制 blob | -| `fdb_kv_set_default(&db)` | 格式化所有 sector 并写入默认值 | -| `fdb_tsdb_init(&db, "tsdb1", "fdb_tsdb1", get_time, 1024, NULL)` | 初始化 TSDB | -| `fdb_tsl_append(&db, data)` | 追加时序记录 | -| `fdb_tsl_iter_by_time(&db, from, to, cb, cb_arg)` | 时间范围查询 | - -### 10.4 FTL/FatFS (via nand_ftl.c / ff.h) +### 8.2 FTL/FatFS (via nand_ftl.c / ff.h) | 函数 | 说明 | |------|------| @@ -532,75 +405,9 @@ f_mkfs("", &opts, work, size) --- -## 11. 使用示例 +## 9. 使用示例 -### 11.1 KVDB 初始化与使用 - -```c -#include "flashdb.h" -#include "fdb_cfg.h" - -/* KVDB 实例 */ -static struct fdb_kvdb g_kvdb; - -static int kvdb_init(void) { - fdb_err_t ret = fdb_kvdb_init(&g_kvdb, "kvdb1", "fdb_kvdb1", NULL, NULL); - return (ret == FDB_NO_ERR) ? 0 : -1; -} - -static void kvdb_example(void) { - /* 写字符串 */ - fdb_kv_set(&g_kvdb, "device_id", "STM32F407-001"); - - /* 读字符串 */ - const char *val = fdb_kv_get(&g_kvdb, "device_id"); - - /* 写二进制 blob */ - struct fdb_blob blob; - uint32_t value = 42; - fdb_blob_make(&blob, &value, sizeof(value)); - fdb_kv_set_blob(&g_kvdb, "counter", &blob); - - /* 读二进制 blob */ - uint32_t read_val; - fdb_blob_make(&blob, &read_val, sizeof(read_val)); - fdb_kv_get_blob(&g_kvdb, "counter", &blob); - - /* 格式化(清除所有数据) */ - fdb_kv_set_default(&g_kvdb); -} -``` - -### 11.2 TSDB 初始化与使用 - -```c -static struct fdb_tsdb g_tsdb; - -static time_t get_timestamp(void) { - return sys_clock_now(); // 从 RTC 获取 Unix 时间戳 -} - -static int tsdb_init(void) { - fdb_err_t ret = fdb_tsdb_init(&g_tsdb, "tsdb1", "fdb_tsdb1", - get_timestamp, 1024, NULL); - return (ret == FDB_NO_ERR) ? 0 : -1; -} - -typedef struct { - float voltage; - float current; - float temperature; -} sensor_data_t; - -static void tsdb_example(void) { - sensor_data_t data = {3.3f, 0.5f, 25.6f}; - struct fdb_blob blob; - fdb_blob_make(&blob, &data, sizeof(data)); - fdb_tsl_append(&g_tsdb, &blob); -} -``` - -### 11.3 FatFS 文件操作 +### 9.1 FatFS 文件操作 ```c #include "ff.h" @@ -639,7 +446,7 @@ static void fatfs_write_read(void) { } ``` -### 11.4 FTL 格式化 +### 9.2 FTL 格式化 ```c #include "nand_ftl.h" @@ -652,12 +459,11 @@ if (nand_ftl_format() == 0) { --- -## 12. 注意事项 +## 10. 注意事项 1. **擦除对齐** — `gd5f2gq5ue_erase()` 的 offset 和 size 必须严格按 GD5F_BLOCK_SIZE (128KB) 对齐和整数倍。 -2. **写前擦除** — NAND 不能原地覆写,FTL 和 FlashDB 内部自动管理擦除,但直接调用 `gd5f2gq5ue_write()` 前必须确保目标块已擦除。 +2. **写前擦除** — NAND 不能原地覆写,FTL 内部自动管理擦除,但直接调用 `gd5f2gq5ue_write()` 前必须确保目标块已擦除。 3. **FTL 首个扇区** — `dhara_map_init` 的第 5 个参数 (journal 页数) 影响 GC 效率,当前为 4,增大可减少写入放大但占用更多内存。 4. **坏块传播** — FTL 在擦除/编程失败后自动调用 `dhara_nand_mark_bad` → `gd5f2gq5ue_mark_block_bad`,BBT 在 RAM 中更新,下次复位后重新扫描出厂坏块并叠加运行时坏块。 5. **功耗** — 擦除操作最大耗时约 5ms (驱动超时设为 5s),页编程约 600ms (超时 1s),读写操作快。在低功耗场景需注意合理安排操作时序。 -6. **分区隔离** — 三个分区物理隔离,FlashDB 操作不会影响 FTL 数据,反之亦然。修改分区布局时需同步更新 `fal_cfg.h` 和确认 FTL 宏自动适配。 -7. **缓存一致性** — 单页缓存 (s_cache_buf) 仅对 FatFS 层可见,多任务读写同一文件需在应用层同步。 +6. **缓存一致性** — 单页缓存 (s_cache_buf) 仅对 FatFS 层可见,多任务读写同一文件需在应用层同步。