FatFs on an SD Card - Write speed drops unless I unmount/mount each time I open a file.
Hello
I have a custom board with a STM32H730 and SD Card connected to the SDMMC peripheral, quad lines. I'm using the FatFs file system as added in CubeMX.
My question is why does the file write rate drop after the first file (open/write/close) unless I mount/unmount each time?
I create a new file and write 1KB of data, its takes about 12ms for the first file. But for subsequent files I create and write the same 1KB of data it then takes around 160ms.
But if I call mount() and unmount() each time when creating and writing the 1kB file, it takes ~12ms each time.
The test program below outputs
File 20 x 800 Byte Write with mount/unmount each time.
> elapsed time = 641 ms
File 20 x 800 Byte Write without one mount/unmount.
> elapsed time = 3522 ms
void CFileSystem::TestWriteSpeed()
{
char wbuff[800] = {0};
char fname[32] = {0};
UINT bytesWritten {0};
FIL file;
uint32_t timens;
printf ( "File 20 x 800 Byte Write with mount/unmount each time.\n" );
timens = osKernelGetTickCount();
for ( int fn=0; fn<20; fn++ )
{
snprintf( fname, sizeof( fname ), "test_file_a_%02d.txt", fn+1 );
if ( FR_OK == f_mount( &SDFatFS, (TCHAR const*)SDPath, 0 ) )
{
if ( FR_OK == f_open( &file, fname, FA_CREATE_ALWAYS | FA_WRITE ) )
{
f_write( &file, wbuff, (UINT)sizeof( wbuff ), (UINT*)&bytesWritten );
f_close( &file );
f_unlink( fname );
}
}
f_mount( 0, "", 0 ); // unmount file system.
}
timens = osKernelGetTickCount() - timens;
printf ( "> elapsed time = %lu ms\n", timens);
printf ( "File 20 x 800 Byte Write without one mount/unmount.\n" );
timens = osKernelGetTickCount();
if ( FR_OK == f_mount( &SDFatFS, (TCHAR const*)SDPath, 0 ) )
{
for ( int fn=0; fn<20; fn++ )
{
snprintf( fname, sizeof( fname ), "test_file_b_%02d.txt", fn+1 );
if ( FR_OK == f_open( &file, fname, FA_CREATE_ALWAYS | FA_WRITE ) )
{
f_write( &file, wbuff, (UINT)sizeof( wbuff ), (UINT*)&bytesWritten );
f_close( &file );
f_unlink( fname );
}
}
f_mount( 0, "", 0 ); // unmount file system.
}
timens = osKernelGetTickCount() - timens;
printf ( "> elapsed time = %lu ms\n", timens);
}
