9ceb218f80
Co-authored-by: Cursor <cursoragent@cursor.com>
3.1 KiB
3.1 KiB
externalflash 模块说明(SPI4 外部 Flash)
本文档描述
CCU621_M/BSP/externalflash模块的职责、接口、初始化位置以及 DMA + D-Cache 场景下的使用注意事项。
1. 模块组成
- 底层驱动(SPI4 + GD25QXX)
exflash_spi4_gd25qxx.cexflash_spi4_gd25qxx.h
- 统一对外接口(业务层推荐使用)
flash_external_data.cflash_external_data.h
2. 初始化入口
- 系统硬件初始化入口:
BSP/sys_drv_init.cv_sys_hardware_init()中调用v_flash_dataflash_init(),完成 SPI4/GPIO/DMA 初始化。
约束:业务层/测试层不要重复 init,避免初始化时序与资源重复配置。
3. 推荐对外接口(统一接口)
业务层请优先使用以下接口(位于 flash_external_data.c/.h):
U8_T v_flash_dataflash_init(void)U8_T s32_flash_dataflash_write(U32_T addr, U8_T *buf, U32_T len)U8_T s32_flash_dataflash_read(U32_T addr, U8_T *buf, U32_T len)U8_T s32_flash_dataflash_erase_sector(U32_T addr)- 兼容旧命名:
unsigned int SPI_flsh_ReadID(void)
3.1 地址规划(摘自 flash_external_data.h)
- 全空间(4-byte 地址模式):
0x00000000 ~ 0x01FFFFFF(32MB) - OTA 区:
0x00000000 ~ 0x001FFFFF - 参数区:
0x210000 ~ ... - 业务记录区:
0x220000 ~ ... - FatFs 映射区:
0xA00000 ~ 0x01FFFFFF
说明:以上为“线性地址”规划,调用统一接口时直接传该地址即可。
4. DMA + D-Cache 使用注意事项(非常重要)
当前 SPI4 外部 Flash 读写采用 DMA 方式提升性能;在 Cortex-M7 开启 D-Cache 的情况下,DMA 与 CPU 会出现数据一致性问题:
- DMA 写入内存后,CPU 可能仍读取到旧 cache 数据;
- DMA 从内存读取 TX 数据时,可能读不到 CPU 刚写入但未 clean 的 cache 内容。
4.1 当前工程的处理策略
- 底层 SPI4 DMA 传输在驱动内部做了 D-Cache clean/invalidate(按 32B cache line 对齐)。
- 统一接口
s32_flash_dataflash_read/write额外做了一层保护:- 如果业务传入的
buf不是 32B 对齐,内部会自动使用 对齐 bounce buffer 完成 DMA 传输,再memcpy到业务缓冲。
- 如果业务传入的
4.2 业务层建议
- 业务层可直接使用
s32_flash_dataflash_read/write,无需自行对齐或自行做 cache 维护。 - 若业务存在高频读写,可考虑在模块内复用一块“32B 对齐的工作缓冲”,减少 malloc/free 次数(后续可优化)。
5. 测试入口
app/app_init/app_test.c- 周期执行 flash 擦写读回校验
- 输出擦除/读写耗时与速度统计
- 新增
u8_app_test_flash_32m_stride_rw():以 1MB 步长扫描 32MB 地址空间做擦写读回校验
6. 常见问题排查
- 读回校验失败
- 首先确认是否走统一接口(避免绕过 bounce buffer)
- 其次检查 D-Cache 是否开启、MPU 区域属性是否覆盖了 DMA buffer
- 卡死在 SPI_FLAG_RP 等待
- 通常表示 SPI 主机传输未启动或时钟未输出,需要检查
spi_master_transfer_start是否调用、片选是否正确、外设时钟是否使能
- 通常表示 SPI 主机传输未启动或时钟未输出,需要检查