/**
- NOR FLASH 驱动配置参数指南
- 本文档详细说明你需要配置的所有参数,以及如何根据硬件实际情况进行调整 */
========================================================================================
第一部分:基础硬件配置(最重要)
========================================================================================
1.1 电源与时钟配置
位置:src/build/config/boards/[你的板子]/config.in
CONFIG_HAS_SFC=y ✅ 启用 SFC 控制器
CONFIG_SFC_CLK_GATE=y ✅ SFC 时钟门控(推荐)
CONFIG_HI_SFC_SPEED_MODE=3 ⚙️ SPI 速度:0=33MHz, 1=66MHz, 2=100MHz, 3=150MHz
CONFIG_SFC_SUPPORT_QUAD=y ⚙️ 是否支持 QUAD SPI(高端芯片)
✅ 验证:确保 SFC 时钟已启用,否则 SFC 读写会失败
1.2 引脚配置
位置:src/board/[你的板子]/board.c 或 board_pin_config.c
需要配置以下 SPI 引脚:
| 信号 | 用途 | 推荐引脚 | 必需 |
|---|---|---|---|
| CLK | 时钟 | GPIO_x | ✅ 必需 |
| MOSI | 主出从入数据线 | GPIO_y | ✅ 必需 |
| MISO | 主入从出数据线 | GPIO_z | ✅ 必需 |
| CS | 片选 | GPIO_w | ✅ 必需 |
| WP | 写保护(Quad SPI) | GPIO_v | ⭕ Quad SPI 需要 |
| HOLD | 暂停(Quad SPI) | GPIO_u | ⭕ Quad SPI 需要 |
配置示例:
hal_gpio_config(GPIO_CLK, GPIO_MODE_AF, GPIO_AF_SFC);
hal_gpio_config(GPIO_MOSI, GPIO_MODE_AF, GPIO_AF_SFC);
hal_gpio_config(GPIO_MISO, GPIO_MODE_AF, GPIO_AF_SFC);
hal_gpio_config(GPIO_CS, GPIO_MODE_AF, GPIO_AF_SFC);
========================================================================================
第二部分:SFC 驱动配置
========================================================================================
2.1 SFC 初始化配置
文件:src/drivers/chips/ws63/porting/sfc/sfc_porting.h
// 宏定义配置
#define SFC_BASE_ADDR 0x40200000 // ✅ SFC 控制器基地址(固定)
#define SFC_AHB_CLOCK_GATE_ADDR 0x4000xxxx // ⚙️ 时钟门控寄存器地址
// Flash 映射配置
#define FLASH_MAPPING_START_ADDR 0x200000 // ⚙️ Flash 在 CPU 地址空间的映射起始
#define FLASH_MAPPING_MAX_SIZE 0x400000 // ⚙️ 映射最大大小(通常 4MB)
2.2 SFC 工作模式配置
在初始化时调用:
sfc_flash_config_t sfc_config = {
.mapping_addr = 0x200000, // ⚙️ 映射地址
.mapping_size = 0x400000, // ⚙️ 映射大小
.read_type = QUAD_READ, // ⚙️ 读模式(见下表)
.write_type = QUAD_PROGRAM, // ⚙️ 写模式(见下表)
.erase_size = ERASE_4K, // ⚙️ 擦除粒度
.auto_switch = 1, // ✅ 自动降级(降速但兼容)
};
uapi_sfc_init(&sfc_config);
读模式选项(read_type)
| 模式 | 性能 | 兼容性 | 使用场景 |
|---|---|---|---|
| STANDARD_READ | 33MHz | 最好 | ✅ 所有芯片通用 |
| FAST_READ | 50MHz | 很好 | 稳定性要求高 |
| DUAL_READ | 66MHz | 中等 | 需要均衡方案 |
| QUAD_READ | 150MHz | 一般 | ✖️ 仅特定芯片支持 |
优先级:STANDARD_READ → FAST_READ → DUAL_READ → QUAD_READ
写模式选项(write_type)
| 模式 | 性能 | 说明 |
|---|---|---|
| PAGE_PROGRAM | 标准 | ✅ 所有芯片支持(推荐) |
| QUAD_PROGRAM | 快速 | 仅部分高端芯片支持 |
建议:先用 PAGE_PROGRAM,确保基础功能正常
2.3 自动芯片检测与配置
SFC 驱动会自动:
- 检测 Flash 芯片 ID
- 在 flash_config_info.c 的表中查找
位置:src/drivers/chips/ws63/porting/sfc/flash_config/flash_config_info.c
支持的芯片列表(可在此添加新芯片):
✅ GigaDevice GD25Q32 (1640C8) - 32Mbit, 推荐用于 WS63
✅ Winbond W25Q32 (1660EF) - 32Mbit, 兼容性好
✅ Winbond W25Q64 (1760EF) - 64Mbit
✅ GigaDevice GD25LQ64 (1760C8) - 64Mbit, 低电压
❌ 其他型号需要自己添加配置
========================================================================================
第三部分:littlefs 分区配置
========================================================================================
3.1 分区配置
文件:src/include/middleware/partition/partition_table.h 或 board_config.json
// littlefs 使用的分区定义
#define CONFIG_LFS_PARTITION_ID 1 // ⚙️ littlefs 分区 ID
#define CONFIG_LFS_START_ADDR 0x200000 // ⚙️ 必须与 SFC 映射地址一致
#define CONFIG_LFS_PARTITION_SIZE 0x40000 // ⚙️ littlefs 分区大小(256KB)
分区布局示例
Flash 地址空间(4MB 总容量):
0x000000 ┌─────────────────┐
│ Boot (512KB) │ ← Bootloader
0x080000 ├─────────────────┤
│ App (1.5MB) │ ← 应用程序
0x200000 ├─────────────────┤
│ littlefs (256KB)│ ← SFC 映射开始
│ (4K blocks) │
0x240000 ├─────────────────┤
│ │
│ User Data Area │ ← 日志文件区
│ (3.5MB+ 剩余) │
│ │
0x400000 └─────────────────┘
⚠️ 重点:
- 确保 littlefs 分区与 SFC 映射地址对齐
- 不要让 app 和 littlefs 分区重叠
- littlefs 分区 = SFC 映射地址的起点
3.2 littlefs 文件系统配置
文件:src/kernel/osal/include/fs_adapt.h 或 littlefs_adapt.h
// Block 配置(必须与硬件一致)
#define LFS_BLOCK_SIZE 4096 // ✅ 固定 4KB
#define LFS_BLOCKS 256 // ⚙️ block 数量 = 分区大小 / 4KB
// 如果分区 256KB,则 256 blocks
// Cache 配置
#define LFS_CACHE_SIZE 16 // ✅ 推荐 16
#define LFS_LOOKAHEAD 16 // ✅ 推荐 16
// 读写配置
#define LFS_READ_SIZE 16 // ✅ 最小读取单位
#define LFS_PROG_SIZE 256 // ⚙️ 编程大小(与 Flash 页大小对应)
========================================================================================
第四部分:日志管理器配置
========================================================================================
4.1 日志存储配置
文件:log_manager.h
// 日志存储位置配置
#define LOG_PARTITION_ID 1 // ⚙️ 使用同一个分区
#define LOG_MOUNT_POINT "/logs" // ⚙️ littlefs 中的日志目录
#define LOG_MAX_FILE_SIZE 1048576 // ✅ 单个日志文件最大 1MB
#define LOG_MAX_FILES 20 // ⚙️ 最多保存 20 个日志文件
// 时间戳配置
#define LOG_TIMESTAMP_FORMAT "YYYYMMDD_HHMMSS" // ✅ 日志文件名时间格式
// 清理策略
#define LOG_CLEANUP_THRESHOLD 10 // ⚙️ 超过 10 个文件时清理旧文件
#define LOG_AUTO_CLEANUP 1 // ✅ 开启自动清理
4.2 Flash 容量配置
// 日志分配的 Flash 空间
#define LOG_TOTAL_SPACE (3 * 1024 * 1024) // ⚙️ 3MB 用于日志
#define MIN_FREE_SPACE (512 * 1024) // ⚙️ 至少保留 512KB
// 监控警告
#define SPACE_WARNING_THRESHOLD (80) // ⚙️ 空间 80% 满时告警
#define CRITICAL_SPACE_THRESHOLD (95) // ⚙️ 空间 95% 满时严重告警
========================================================================================
第五部分:调试与验证
========================================================================================
5.1 编译配置
在 CMakeLists.txt 中确保启用调试符号和日志:
# 调试级别
set(CMAKE_BUILD_TYPE Debug)
# 编译选项
add_compile_options(-g) # 调试符号
add_compile_options(-O0) # 关闭优化(便于调试)
add_compile_options(-DDEBUG_SFC=1) # ⚙️ SFC 调试日志
add_compile_options(-DDEBUG_LFS=1) # ⚙️ littlefs 调试日志
add_compile_options(-DDEBUG_LOG=1) # ⚙️ 日志管理器调试
5.2 日志输出配置
启用以下调试输出:
#define DEBUG_SFC 1 // ⚙️ 打印 SFC 操作日志
#define DEBUG_LFS 1 // ⚙️ 打印 littlefs 操作日志
#define DEBUG_LOG_MGR 1 // ⚙️ 打印日志管理器操作
#define DEBUG_PERF 1 // ⚙️ 打印性能指标
========================================================================================
第六部分:常见问题排查
========================================================================================
问题 1:SFC 初始化失败
▶ 症状:uapi_sfc_init() 返回错误
✅ 检查清单:
- CONFIG_HAS_SFC=y 已启用
- SPI 引脚已正确配置
- Flash 芯片与驱动板连接正确
- 硬件电源正常(3.3V)
- Flash 芯片不是坏的或损坏的
▶ 调试步骤:
errcode_t ret = uapi_sfc_init(&config);
printf("SFC init result: 0x%X\n", ret);
if (ret != ERRCODE_SUCC) {
printf("Error code meaning: %s\n", get_error_string(ret));
}
问题 2:Flash ID 检测失败
▶ 症状:读到的 ID 是 0xFFFFFFFF 或 0x000000
✅ 检查清单:
- SPI CLK 信号是否正常
- MISO 线连接有无松动
- CS 线是否被正确拉低
- 检查示波器上是否有时序波形
▶ 调试步骤:
uint32_t flash_id;
hal_sfc_get_flash_id(&flash_id);
printf("Flash ID: 0x%06X\n", flash_id & 0xFFFFFF);
// 查询支持列表
if (flash_id not in supported_list) {
printf("Warning: Flash chip not in support list!\n");
}
问题 3:littlefs 挂载失败
▶ 症状:fs_adapt_mount() 失败或 fs_adapt_open() 返回错误
✅ 检查清单:
- 分区地址与 SFC 映射地址一致
- littlefs 分区不能与其他分区重叠
- 上次未正常卸载文件系统
- Flash 空间不足
▶ 调试步骤:
int ret = fs_adapt_mount();
if (ret != LFS_ERR_OK) {
printf("littlefs mount failed: %d\n", ret);
// 尝试格式化
fs_adapt_format(); // ⚠️ 这会清除所有数据!
}
问题 4:文件读写正教失败
▶ 症状:写入成功但读不出来
✅ 检查清单:
- 是否调用了 fs_adapt_sync() 或 fsync()
- 文件指针是否在正确位置
- 有无缓冲区溢出
- Flash 是否损坏
▶ 调试步骤:
int fd = fs_adapt_open("/test.txt", O_RDWR | O_CREAT);
int written = fs_adapt_write(fd, "test", 4);
fs_adapt_sync(fd); // ⚠️ 必须调用
fs_adapt_lseek(fd, 0, SEEK_SET); // 重置指针
char buf[10];
int read = fs_adapt_read(fd, buf, 4);
printf("Wrote %d, Read %d\n", written, read);
问题 5:性能低于预期
▶ 症状:读写速度 < 10MB/s(预期 150MB/s)
✅ 检查清单:
- 是否使用了 QUAD_READ 模式
- SFC 时钟频率是否设置最高 (150MHz)
- 是否有系统滴答中断影响
- Cache 是否启用
▶ 调试步骤:
// 检查配置
printf("SFC Read Mode: %d (0=STANDARD, 3=QUAD)\n", sfc_config.read_type);
printf("SFC Clock: %dMHz\n", sfc_get_clock_mhz());
// 运行性能测试
test_read_performance();
========================================================================================
第七部分:配置清单(实施步骤)
========================================================================================
第一步:物理硬件验证
- 确认 Flash 芯片型号(标签上印的)
- 检查 SPI 接线:CLK, MOSI, MISO, CS
- 使用万用表测量电源电压(3.3V ± 0.2V)
- 用示波器观察 SPI 时序
第二步:驱动配置
- 在 build config 中启用 SFC (CONFIG_HAS_SFC=y)
- 配置 SPI 引脚映射
- 检查 Flash 芯片是否在 flash_config_info.c 支持列表中
- 设置 SFC 时钟频率为 150MHz
第三步:分区配置
- 确定 littlefs 分区起始地址和大小
- 更新 CONFIG_LFS_START_ADDR 与 SFC 映射地址对齐
- 确保分区不重叠
第四步:littlefs 配置
- 设置 LFS_BLOCK_SIZE = 4096
- 计算 LFS_BLOCKS = 分区大小 / 4096
- 设置 LFS_PROG_SIZE = 256
第五步:日志管理器配置
- 设置 LOG_MOUNT_POINT = "/logs"
- 设置 LOG_MAX_FILE_SIZE = 1MB
- 设置 LOG_MAX_FILES = 20
第六步:编译与测试
- 编译驱动:
make - 烧录到板子
- 运行测试套件:
nor_flash_driver_test_suite - 查看测试结果报告
========================================================================================
总结
========================================================================================
| 配置项 | 文件位置 | 优先级 | 说明 |
|---|---|---|---|
| CONFIG_HAS_SFC | board config | 🔴 必须 | 启用 SFC |
| SPI 引脚映射 | board.c | 🔴 必须 | CLK/MOSI/MISO/CS |
| Flash 芯片型号 | flash_config_info.c | 🔴 必须 | 决定支持的模式 |
| SFC 时钟频率 | sfc_porting.h | 🟡 重要 | 影响性能 |
| littlefs 分区地址 | partition.h | 🔴 必须 | 与 SFC 映射对齐 |
| littlefs 分区大小 | partition.h | 🟡 重要 | 决定容量 |
| 日志目录 | log_manager.h | 🟢 次要 | 默认即可 |
| 日志文件大小限制 | log_manager.h | 🟢 次要 | 默认 1MB 即可 |
下一步:运行 nor_flash_driver_test_suite 验证所有配置是否正确!