cancel
Showing results for 
Search instead for 
Did you mean: 

FatFs on an SD Card - Write speed drops unless I unmount/mount each time I open a file.

David George
Associate III

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);

}

 

 

 

5 REPLIES 5

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

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

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.

 

Hi,

Is your time ( always mount and unmount) 643 ms including the mount time or just the writing time?

If you feel a post has answered your question, please click "Accept as Solution".

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()

 

 

 

Hi,

Your test seems a bit strange to me, because you complain about writing time, but same time include many other fat functions.

So try without unlink() and just open, write, close 20 files in one sequence, name test1 ...test20 .

And then also test the most common way: 

mount with parameter 1 , mount NOW, .then:

Open one file, with FA_OPEN_APPEND ,then write 1kB or so, and do this write 20 times, so it gets a 20KB file.

Then you see more, how much time for writing and not for other fat functions.

If you feel a post has answered your question, please click "Accept as Solution".