EmbeddedRelated.com
Forums

unable to read large file with Fatfs using f_read() and f_gets()

Started by kunalb 7 years ago5 replieslatest reply 7 years ago3258 views

I'm tring to read microSD card with #MSP430 controller and FatFs in SPI mode.

The file on microSD is a 64KB CSV file with entries like these:

2/2/2017,11:17:17,120056,250,0,72.8,8.1,8.2,12.1,0.17,0.1 (\n at end of each line)

There are about 800 entries in the file. The problem is that when I use f_gets(), I can only read about 20kB and then f_gets returns with 0 bytes read. 20KB is around 270 lines in the file. When I use f_lseek(x) before starting to read, then I am able to read upto (x + 20KB). 

When f_gets() stops reading, the file pointer fptr is always a multiple of 512. The sector size is 512 bytes. So for some reason it halts at the sector boundary but only after reading about 20KB.(19511, 20296, 23374 bytes, etc to be exact).

fMountStatus = f_mount (&myFs, "0:", 1);
    delayCount =50000;            // 110 ms        
    while (delayCount--);    
fOpenStatus = f_open(&fileObject, fileName, FA_OPEN_EXISTING | FA_READ);
    delayCount =50000;            // 110 ms        
    while (delayCount--);
    
while(f_tell(&fileObject)  <  f_size(&fileObject))
{   fptrBeforeFgets = f_tell(&fileObject);  
    f_gets(readBuffer, sizeof(readBuffer), &fileObject);// char readBuffer[200]  
    fptrAfterFgets = f_tell(&fileObject);    
    if(fptrAfterFgets == fptrBeforeFgets)  
        {
            // f_gets failed 
        }
}

I'm using MSP debugger to watch FIL structure and 'readBuffer' array.

I tried using f_read() and found the same issue, just that f_read() could read 30KB before returning FR_DISK_ERR.(30808, 30688, 30230, etc bytes to be exact).

fMountStatus = f_mount (&myFs, "0:", 1);
    delayCount =50000;            // 110 ms
    while (delayCount--);
fOpenStatus = f_open(&fileObject, fileName, FA_OPEN_EXISTING | FA_READ);
    delayCount =50000;            // 110 ms
    while (delayCount--);

while(f_tell(&fileObject)  <  f_size(&fileObject))
{
     bytesToRead = 1024;    // tried with 512, 1000 too
     fReadStatus = f_read(&fileObject, readBuffer, bytesToRead, &bytesRead);

     delayCount =50000;            // 110 ms
     while (delayCount--);
}

I tried f_close() after seeing this issue. It returns FR_OK but f_open() after that returns FR_DISK_ERR. I have to give it power reset to read smoothly again from SD card.

microSD= SanDisk SDHC 8GB, cluster size= 64KB.

FatFs(R0.12b), FAT32.

SPI clock = 200kHz.

Can any one please help me solve this issue ?

Has any one read a large file using Fatfs with no problem?

--

Thanks

[ - ]
Reply by Tim WescottFebruary 9, 2017

I do not have an answer to your question.

However, I've got a project on my bench, currently stalled, that uses FatFs.  I also have a unit-test suite for FatFs that runs on my desktop.  So I may have some insight.

If I were in your shoes, I would get FatFs running on your desktop computer, in an environment that has a decent debugger (I'm running Linux/gcc/Eclipse).  I'd see if I could replicate the problem on my local machine.  If I could, then I'd be happy, because then I could use the debugger to start figuring out what's going on.  If I couldn't, then I'd be happy because I'd know that there's something about the difference between my desktop machine and the MPS430 that's the root of the problem.

If it works on your desktop and not for real, then it's either the integer size or it's a timing issue.  If you were just reporting the read problems, the fact that things happen at close to \( 2^{15} \) would make me suspicious -- but 24,000 is a long way away from 32768.

Are you reading this stuff out as fast as you can, or are you giving things time to rest?  It may just be that you're going too fast for something, and it takes that long for reality to catch up to you.  If you don't want to get the filesystem working on your desktop, it might be informative to just stick a delay loop in there someplace, or otherwise throttle things down.

[ - ]
Reply by kunalbFebruary 9, 2017

Hi Tim,

Thanks for your analysis.

>>>Are you reading this stuff out as fast as you can, or are you giving things time to rest?

I dont have a hard requirement of reading very fast. I introduced ~100ms delay between all file operations just in case the SD card needs its own processing time. I will try slowing it further to see if it helps.


[ - ]
Reply by Ivan Cibrario BertolottiFebruary 9, 2017

Hello,

I concur with Tim about a possible timing issue.  This is because, in a correctly integrated FatFs system (that is, with a hardware/RTOS adaptation layer that is working properly) the delay loops I see in your code should be totally unnecessary because FatFs (or, better, the adaptation layer) should ensure the filesystem is correctly synchronized with hardware.

In other word, it should never be necessary to insert any explicit wait between FatFs calls, something your code seems to do instead.

I would start from that.

Cheers,
Ivan


[ - ]
Reply by kunalbFebruary 9, 2017

Hi Ivan,

Thanks for responding.

I introduced delays between Fatfs calls so as to not rush the SD card and to give it time for its internal memory operations, something that I learnt while using Fatfs earlier for writing to SD card.

Any way, I shall try removing the delays but I expect to see more problems with that.

[ - ]
Reply by Ivan Cibrario BertolottiFebruary 9, 2017

That's exactly my point... if FatFs works better or worse depending on whether or not you introduce manual delays it indicates that something is seriously wrong with timings.  The problem is probably with the adaptation layer that does not properly synchronize the FatFs library with the underlying hardware.