本在STM32F1上移植了FATFS系统,然后又将项目移植到GD32F1上去。发现在使用文件系统频繁写入时接口报错;
报错“SD_TX_UNDERRUN”或者“SD_RX_OVERRUN”,初期通过f_open、f_lseek、f_write、f_close之间加上10ms延时是可以用的,但是还是不够稳定。我每次写入数据量大概在2K,连续需要写入次数大概是上千次。
解决方案就需要在FATFS系统的驱动中加入临界保护。如以下写入案例:
DRESULT SD_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count)
{
DRESULT res = RES_OK;
taskENTER_CRITICAL(); /* 临界保护开启 */
if ((DWORD)buff & 3)
{
DRESULT res = RES_OK;
DWORD scratch[BLOCK_SIZE / 4];
while (count--)
{
memcpy( scratch,buff,BLOCK_SIZE);
res = SD_write(lun,(void *)scratch, sector++, 1);
if (res != RES_OK)
{
break;
}
buff += BLOCK_SIZE;
}
return res;
}
if(HAL_SD_WriteBlocks(&SD_Handle, (uint32_t*)buff, (uint64_t)(sector * BLOCK_SIZE), BLOCK_SIZE, count) != HAL_OK)
{
res = RES_ERROR;
}
taskEXIT_CRITICAL(); /* 临界保护关闭 */
return res;
}
同样的读取也需要加入临界断:
DRESULT SD_read(BYTE lun, BYTE *buff, DWORD sector, UINT count)
{
DRESULT res = RES_OK;
taskENTER_CRITICAL(); /* 临界保护开启 */
if ((DWORD)buff & 3)
{
DWORD scratch[BLOCK_SIZE / 4];
while (count--)
{
res = SD_read(lun,(void *)scratch, sector++, 1);
if (res != RES_OK)
{
break;
}
memcpy(buff, scratch, BLOCK_SIZE);
buff += BLOCK_SIZE;
}
return res;
}
if(HAL_SD_ReadBlocks_DMA(&SD_Handle, (uint32_t*)buff, (uint64_t)(sector * BLOCK_SIZE), BLOCK_SIZE, count) != HAL_OK)
{
res = RES_ERROR;
}
if(res==RES_OK)
{
if(HAL_SD_CheckReadOperation(&SD_Handle, 0xFFFFFFFF) != HAL_OK)
{
res = RES_ERROR;
}
}
taskEXIT_CRITICAL(); /* 临界保护关闭 */
return res;
}