cancel
Showing results for 
Search instead for 
Did you mean: 

f_lseek returning FR_INT_ERROR in stm FATFS

shefu
Associate II

Hello,

I am trying to interface the sdcard FAT32 based on SPI with STM32F429ZI MCU. I am using the FATFS library (R0.12c) provided in the stmcube ide.

I am able to successfully initialize the sdcard using f_mount() function.

I want to implement the below mentioned code. f_open is sending the FR_OK response that means file is opened successfully but f_lseek command is not responding correctly.

fres = f_open(&fil,"HEADER.TXT", FA_READ | FA_OPEN_EXISTING);
if(fres == FR_OK)
{
fres = f_lseek(&fil,2);
fres = f_read(&fil,&temp,3, &ptr);
fres = f_close(&fil);
}

It is also came to my notice that when I send the command fres = f_lseek(&fil,0); then it responds FR_OK. Any non zero value in f_lseek function responds to the FR_INIT_ERROR.

 

During Debugging:  in my case ofs =2

bcs = (DWORD)fs->csize * SS(fs); /* Cluster size (byte) */  --> this line results in bcs= 0 since the fs_csize is 0

ofs -= bcs; fp->fptr += bcs;     --> Due to bcs=0 this line does not have any effect

clst = get_fat(&fp->obj, clst);     --> this function return 0, here clst is passed as 24

if (clst <= 1 || clst >= fs->n_fatent) ABORT(fs, FR_INT_ERR);   --> since clst = 0 it result in FR_INIT_ERROR

 

I am not able the infer the error from this debugging process. Please help me to find the issue and solution to resolve the issue.

I am attaching the I/O level implementation files and middleware is same as provided by stmcube ide while building the code using .ioc file.

5 REPLIES 5

So an Internal Error.

I'd suggest migrating to a more current version of the FatFs implementation. 

You should check the file size before seeking. 

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

I am using the code generation from the CUBEMX and in the FATFS implementation library involved is by default version (R0.12c). Can you suggest me how can I use the Newest version of the FATFS library in my project?

 

You'll need to do it manually.

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

Hello,

I have manually modified the FATFS library of the STMCUBEIDE to version R0.15 as available on http://elm-chan.org/fsw/ff/   link.

After modifying the library F_lseek command is responding to FR_OK and the file pointer is also moving. But I have observed issue in the f_read command. It sends the FR_OK message but the received byte buffer is empty that means no bytes have been read from the file.

for ( ; btr > 0; btr -= rcnt, *br += rcnt, rbuff += rcnt, fp->fptr += rcnt) { /* Repeat until btr bytes read */

The above loop is executed only single time. Next time it does not enter inside the loop and return to the LEAVE_FF(fs, FR_OK);

 

FRESULT f_read (
FIL* fp, /* Open file to be read */
void* buff, /* Data buffer to store the read data */
UINT btr, /* Number of bytes to read */
UINT* br /* Number of bytes read */
)
{
FRESULT res;
FATFS *fs;
DWORD clst;
LBA_t sect;
FSIZE_t remain;
UINT rcnt, cc, csect;
BYTE *rbuff = (BYTE*)buff;


*br = 0; /* Clear read byte counter */
res = validate(&fp->obj, &fs); /* Check validity of the file object */
if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */
if (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */
remain = fp->obj.objsize - fp->fptr;
if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */

for ( ; btr > 0; btr -= rcnt, *br += rcnt, rbuff += rcnt, fp->fptr += rcnt) { /* Repeat until btr bytes read */
if (fp->fptr % SS(fs) == 0) { /* On the sector boundary? */
csect = (UINT)(fp->fptr / SS(fs) & (fs->csize - 1)); /* Sector offset in the cluster */
if (csect == 0) { /* On the cluster boundary? */
if (fp->fptr == 0) { /* On the top of the file? */
clst = fp->obj.sclust; /* Follow cluster chain from the origin */
} else { /* Middle or end of the file */
#if FF_USE_FASTSEEK
if (fp->cltbl) {
clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
} else
#endif
{
clst = get_fat(&fp->obj, fp->clust); /* Follow cluster chain on the FAT */
}
}
if (clst < 2) ABORT(fs, FR_INT_ERR);
if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
fp->clust = clst; /* Update current cluster */
}
sect = clst2sect(fs, fp->clust); /* Get current sector */
if (sect == 0) ABORT(fs, FR_INT_ERR);
sect += csect;
cc = btr / SS(fs); /* When remaining bytes >= sector size, */
if (cc > 0) { /* Read maximum contiguous sectors directly */
if (csect + cc > fs->csize) { /* Clip at cluster boundary */
cc = fs->csize - csect;
}
if (disk_read(fs->pdrv, rbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR);
#if !FF_FS_READONLY && FF_FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */
#if FF_FS_TINY
if (fs->wflag && fs->winsect - sect < cc) {
memcpy(rbuff + ((fs->winsect - sect) * SS(fs)), fs->win, SS(fs));
}
#else
if ((fp->flag & FA_DIRTY) && fp->sect - sect < cc) {
memcpy(rbuff + ((fp->sect - sect) * SS(fs)), fp->buf, SS(fs));
}
#endif
#endif
rcnt = SS(fs) * cc; /* Number of bytes transferred */
continue;
}
#if !FF_FS_TINY
if (fp->sect != sect) { /* Load data sector if not in cache */
#if !FF_FS_READONLY
if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */
if (disk_write(fs->pdrv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
fp->flag &= (BYTE)~FA_DIRTY;
}
#endif
if (disk_read(fs->pdrv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache */
}
#endif
fp->sect = sect;
}
rcnt = SS(fs) - (UINT)fp->fptr % SS(fs); /* Number of bytes remains in the sector */
if (rcnt > btr) rcnt = btr; /* Clip it by btr if needed */
#if FF_FS_TINY
if (move_window(fs, fp->sect) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Move sector window */
memcpy(rbuff, fs->win + fp->fptr % SS(fs), rcnt); /* Extract partial sector */
#else
memcpy(rbuff, fp->buf + fp->fptr % SS(fs), rcnt); /* Extract partial sector */
#endif
}

LEAVE_FF(fs, FR_OK);
}

 

Why this issue is happening even after modifying the current FATFS system library?

Please suggest the solution of the above bug.

 

Hello,

In the f_read function below line of the code does not have any impact on the rbuff. rbuff still remains empty when I am reading 3 bytes from the 3rd location of the file. My current file size is 102 bytes. f_lseek function increased the file pointer to the 3rd byte location.

memcpy(rbuff, fp->buf + fp->fptr % SS(fs), rcnt); /* Extract partial sector */

Here rcnt also set to 3,  SS(fs) value is 512 and fp-> ptr value is 2.

Why the rbuff buffer is empty?