2024-12-11 03:59 AM
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);
}
2024-12-11 04:10 AM - edited 2024-12-11 04:14 AM
Write multiples of the 512 byte sector size, up to 32KB as buffering permits.
Alignment will reduce a lot of unnecessary reads and writes.
Pace probably comes from how it manages FAT to find free space or open space in directory
2024-12-11 04:32 AM
Hi,
Have tried 2 x f_write() with 512 bytes of data each time, output is..
File 20 x 512 Byte Write with mount/unmount each time.
> elapsed time = 643 ms
File 20 x 512 Byte Write with one mount/unmount.
> elapsed time = 3522 ms
Still takes significantly longer unless I call f_mount(), f_unmount() each time I open/write/close the file.
2024-12-11 05:46 AM
Hi,
Is your time ( always mount and unmount) 643 ms including the mount time or just the writing time?
2024-12-11 06:00 AM
Hi.
The times quoted include the f_mount() and f_unmount() times.
However actual f_mount() and f_unmount() times are fast (<1ms).
This is around 643ms for the 20 x 1kB writes.
for ( i=0; i<20; i++ ) {
f_mount(), f_open(), f_write(), f_close(), f_unlink(), f_unmount()
}
This is at least 3500ms for the same 20 x 1kB writes. When i=0 it takes ~16ms, when i>0 it takes ~160ms
f_mount()
for ( i=0; i<20; i++ ) {
f_open(), f_write(), f_close(), f_unlink()
}
f_unmount()