FatFS f_write not working

Aymen picture Aymen · Mar 26, 2016 · Viewed 10.9k times · Source

I am on a ZedBoard and I am trying to write on an SD card. I am working on an embedded system and I dont have any OS, I am running baremetal.

I can read fine from the SD card, their is no problem.

But when I triy to read, I have some weird behaviour :

  • f_write returns FR_OK
  • The bw (bytes written) variable is correct
  • The file is created (I can see it when I read the SD card from my PC)

But when I read the file, it is empty.

Here is my code :

void WriteFile(char const* fileName, char* buffer, size_t size)
{
    FIL file;
    FATFS fs;
    UINT bw;
    FRESULT fr;

    f_mount(&fs, "", 0);
    f_open(&file, fileName, FA_WRITE | FA_CREATE_ALWAYS);
    fr = f_write(&file, buffer, size, &bw);
    if (size != bw || fr != FR_OK)
        PRINT(("Error in writing !\n"));
    f_close(&file);
    f_mount(NULL, "", 0);
}

And I call the method like this :

 WriteFile("Hello.txt", "Hello World !", 13);

Any idea what I am doing wrong ?

Answer

Aymen picture Aymen · May 8, 2016

I found a little hack that answered my problem :
Basically it doesn't write on the SD card because the buffer isn't full yet (in the low level API of XILINX).
So what I did is pretty simple : I write the data once. And while the size of the file isn't equal or greater than the size of the data written, I write 0 (by blocks of 32)
Also, another important thing : the data you write MUST be 32 bytes aligned !\ Here is my (working) code :

size_t SizeOfFile(char const *path)
{
    FILE *fp = fopen(path, "r");
    fseek(fp, 0, SEEK_END);
    size_t fsize = (size_t) ftell(fp);
    fclose(fp);
    return fsize;
}

void WriteFile( char const* fileName, char* buffer, size_t size )
{
    size_t allignement = ( size + 32 - 1 ) & ~ ( 32 - 1 );  // We must allign by 32
    char* Buffer_logger = pleb_malloc( allignement );
    pleb_memset( Buffer_logger, 0, allignement );
    pleb_memcpy( Buffer_logger, buffer, size );

    unsigned int BytesWr;
    size_t accum = 0;
    result = f_open( &file, fileName, FA_CREATE_ALWAYS | FA_WRITE | FA_READ );
    if ( result != 0 )
    {
        return;
    }

    sprintf( Buffer_logger, "%s", buffer );

    while ( SizeOfFile( fileName ) == 0 )
    {
        // Open log for writing
        result = f_open( &file, fileName, FA_WRITE );
        if ( result != 0 )
        {
            return;
        }

        // Point to the EOF
        result = f_lseek( &file, accum );
        if ( result != 0 )
        {
            return;
        }

        // Write to log
        result = f_write( &file, (const void*) Buffer_logger, size, &BytesWr );
        if ( result != 0 )
        {
            return;
        }

        accum += accum + strlen( Buffer_logger );

        //Close file.
        result = f_close( &file );
        if ( result != 0 )
        {
            return;
        }

        pleb_memset( Buffer_logger, 0, allignement );

        size = 32;
        pleb_memset( Buffer_logger, 0, size );
    }
    pleb_free( Buffer_logger );
    PRINT( ("Data written to log Successfully\r\n") );
}