我在 main 函数里开启 D-Cache:
/* Enable D-Cache---------------------------------------------------------*/
SCB_EnableDCache();
我认为需要取消`sd_diskio.c`第 63 行注释,启用缓存维护宏:
/* USER CODE BEGIN enableSDDmaCacheMaintenance */
#define ENABLE_SD_DMA_CACHE_MAINTENANCE 1
/* USER CODE END enableSDDmaCacheMaintenance */
开启后,通过 DMA 从 SD 卡读取完成后会执行下面这段缓存失效代码:
#if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1)
/*
the SCB_InvalidateDCache_by_Addr() requires a 32-Byte aligned address,
adjust the address and the D-Cache size to invalidate accordingly.
*/
alignedAddr = (uint32_t)buff & ~0x1F;
SCB_InvalidateDCache_by_Addr((uint32_t*)alignedAddr, count*BLOCKSIZE + ((uint32_t)buff - alignedAddr));
我发现:虽然我给 FATFS 分配的缓冲区本身是 32 字节对齐的,但缓冲区传到`sd_diskio.c`这个函数的时候,地址不再保持对齐。
FATFS 内部会占用缓冲区前面若干字节,缓存失效操作会覆盖这部分前置字节,最终导致`f_open`调用失败。
我在`sd_diskio.c`大约 216 行、DMA 配置代码前面增加两行代码修复该问题:
alignedAddr = (uint32_t)buff & ~0x1F;
SCB_CleanDCache_by_Addr((uint32_t*)alignedAddr, ((uint32_t)buff - alignedAddr));
位置就在`BSP_SD_ReadBlocks_DMA`调用之前:
if(BSP_SD_ReadBlocks_DMA((uint32_t*)buff,
(uint32_t) (sector),
count) == MSD_OK)
我还没有进行完整验证,有可能其他位置也有同样问题。
|
|