Electronic – Unable to read file greater than 2K in FatFS

flashfreertosstm32stm32f10x

I am reading a file from the SPI Flash with FATFS file system, on STM32F103 platform running FreeRTOS. I can successfully read File of size less the 2048, but if read a file file of size greater than 2048, (As i am reading in chunks of 128 bytes) it only reads up to 2048 bytes and f_read returns 'FR_INT_ERR' error when File pointer move to location above 2048 bytes.

Below in my code for Read write test. f_size is show the correct file size. But when I read, it gives error, If I focefully run the loop till end of file for reading data it always returns the last chunk before 2048 bytes again and again.

FRESULT xRes;
FIL xFile;
const char cWBuffer[] = "Hello FAT World! 0123456789abcdef";
char cRBuffer[128]

xRes = f_mount(0, &s_xVolume);
printf("\r\n mount result %d successful!",xRes);

#ifdef FAT_MAKEFS_TEST
    // this delay is to prevent the FAT corruption after a systenm reset.
    Delay_us( 200 );

    printf("\r\n MAKE FS Test");
    printf("\r\n format the ext FLASH");
    printf("\r\n please wait...");
    xRes = f_mkfs(0, SFD_FORMAT, 4096 *10 );
    printf("\r\n Format result : %d ",xRes);
    assert(xRes == FR_OK);
#endif

#ifdef FAT_WRITE_TEST
    Delay_us( 1000 );

    printf("\r\n WRITE Test");
    printf("\r\n open file: W+CA");
    xRes = f_open(&xFile, filename, FA_WRITE|FA_CREATE_ALWAYS);
    printf("\r\n Open result : %d ",xRes);
    assert(xRes == FR_OK);

    printf("\r\n write file");
    for(i=0;i<1024;i++)
    {
        xRes = f_write(&xFile, cWBuffer, strlen(cWBuffer), &n);
        //printf("\r\n Write result : %d, bytes = %d ",xRes,n);
        assert(xRes == FR_OK);
        //assert(n == strlen(cWBuffer));
    }

    printf("\r\n close file");
    xRes = f_close(&xFile);
    assert(xRes == FR_OK);

#endif

#ifdef FAT_READ_TEST
    Delay_us( 100 );

    printf("\r\n READ Test");
    printf("\r\n open file: R+OE");
    xRes = f_open(&xFile, filename, FA_READ|FA_OPEN_EXISTING);
    printf("\r\n Open result : %d ",xRes);
    assert(xRes == FR_OK);

    fs = f_size(&xFile);

    printf("\r\n read file size = %d",fs);
    i=0;
    fs = f_size(&xFile);
    while(i<fs)
    {
        xRes = f_read(&xFile, cRBuffer, sizeof(cRBuffer), &m);
        printf("\r\n Read result : %d, bytes read = %d, i =%d ",xRes,m,tread);
        tread += m;
        assert(xRes == FR_OK);
        //assert(m == strlen(cWBuffer));
    }
    printf("\r\n Total bytes read = %d",tread);
    printf("\r\n close file");
    printf("\r\n file content:");
    printf("%s :\n",cRBuffer);
    xRes = f_close(&xFile);
    assert(xRes == FR_OK);
#endif
printf("\r\n test success!!!");

Best Answer

I can't speak to FreeRTOS f_read() call, but for some operating systems, f_read() can only read up the the boundary of the sector size of the underlying media, typically 512 or 2048 bytes. To read more data than that, the f_read() call would need to implement a gather function, reading data from multiple sectors.

We've seen this behavior in nuttx, and I suspect FreeRTOS does the same. To read a larger file, try reading it in blocks sized to your media.