2020-07-29 07:38 AM
I'm using FATfs library for implementing file system on external flash.
Flash is 16MB memory where I can erase minimum of 4kb subsector and total no of subsectors are 4096, so there will be 1 sector per cluster. I've created 2 files
but I see both files are assigned with same sector no i.e sector 10.
So if I write 2nd file data written into first file gets erased.
Do we've to assign sector nos manually?
/* Create and Open a new text file object with write access */
if(f_open(&MyFile, "0:/0:/STM.TXT.TXT", FA_READ | FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)//FA_CREATE_ALWAYS | FA_WRITE
{
/* 'STM32.TXT' file Open for write Error */
Error_Handler();
}
else
{
/* Write data to the text file */
res = f_write(&MyFile, wtext, sizeof(wtext), (void *)&byteswritten);
if((byteswritten == 0) || (res != FR_OK))
{
/* 'STM32.TXT' file Write or EOF Error */
Error_Handler();
}
else
{
/* Close the open text file */
if(f_open(&MyFile2, "0:/RTM.TXT", FA_READ | FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)//FA_CREATE_ALWAYS | FA_WRITE
{
/* 'STM32.TXT' file Open for write Error */
Error_Handler();
}
/* Open the text file object with read access */
else
{
res = f_write(&MyFile2, wtext2, sizeof(wtext2), (void *)&byteswritten);
if((byteswritten == 0) || (res != FR_OK))
{
/* 'STM32.TXT' file Write or EOF Error */
Error_Handler();
}
/* Read data from the text file */
f_close(&MyFile);
f_close(&MyFile2);
f_open(&MyFile, "0:/STM.TXT", FA_READ | FA_OPEN_EXISTING);
res = f_read(&MyFile, rtext, sizeof(rtext), (void *)&bytesread);
f_open(&MyFile2, "0:/RTM.TXT", FA_READ | FA_OPEN_EXISTING);
res = f_read(&MyFile2, rtext2, sizeof(rtext2), (void *)&bytesread);
if((bytesread == 0) || (res != FR_OK))
{
//'STM32.TXT' file Read or EOF Error
Error_Handler();
}
Thanks,
Solved! Go to Solution.
2020-07-29 09:50 AM
Hi,
Just a 2 cents comment.
Using the FatFs with external Flash is not really recommended, because FatFs doesn't manage either wear leveling or bad blocks.Thus you may get you flash quickly damaged. So If you don't have any particular constraint for using FatFs I'd suggest the littlefs as a better alternative.
regards
Haithem.
2020-07-29 08:01 AM
Should work with a sector size of 4K configured in FatFs. Make sure to have enough stack and buffering to cover the larger expectations.
Would want to use most current release of FatFs
Show code instrumentation in DISKIO
Show log of read/write sector requests serviced by DISKIO
Ideally have the DISKIO code generate a CRC of sectors as read/written so you can confirm that the same data you wrote is recovered later.
2020-07-29 09:26 AM
I thought if we create multiple files in same drive then sector no assigned to file object should be different
for example
file1 - "0:/STM.TXT"
file2 - "0:/RTM.TXT"
then STM.TXT should start from sector no 8 as sector no 0 to 7 are for storing FAT and directory entry data then RTM.TXT file should start from sector 9,
but both files STM.TXT and RTM.TXT are assigned with sector no 8, I've checked in debug mode that fp->clst is 0 and fp->sect is 8.
I've one doubt in f_open function are loaded with default cluster no, so for every new file created it'll assign same sector no.
cl = LD_CLUST(dir); /* Get start cluster */
ST_CLUST(dir, 0); /* cluster = 0 */
my question do we need to change this code and assign sector no as per the files we create.
if my 1st file I want to create for size 8kb then I will have to assign sector no 8 to it
for 2nd file I'll have to assign sector no 10. so above lines will be changed to
cl = (first_file_size) + LD_CLUST(dir); /* Get start cluster */
ST_CLUST(dir, cl); /* cluster = 0 */
here fist_file_size will be 2 as first file created was of 8kb size.
FRESULT f_open (
FIL *fp, /* Pointer to the blank file object */
const TCHAR *path, /* Pointer to the file name */
BYTE mode /* Access mode and file open mode flags */
)
{
FRESULT res;
DIR dj;
BYTE *dir;
DEF_NAMEBUF;
fp->fs = 0; /* Clear file object */
#if !_FS_READONLY
mode &= FA_READ | FA_WRITE | FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW;
res = chk_mounted(&path, &dj.fs, (BYTE)(mode & ~FA_READ));
#else
mode &= FA_READ;
res = chk_mounted(&path, &dj.fs, 0);
#endif
INIT_BUF(dj);
if (res == FR_OK)
res = follow_path(&dj, path); /* Follow the file path */
dir = dj.dir;
#if !_FS_READONLY /* R/W configuration */
if (res == FR_OK) {
if (!dir) /* Current dir itself */
res = FR_INVALID_NAME;
#if _FS_SHARE
else
res = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0);
#endif
}
/* Create or Open a file */
if (mode & (FA_CREATE_ALWAYS | FA_OPEN_ALWAYS | FA_CREATE_NEW)) {
DWORD dw, cl;
if (res != FR_OK) { /* No file, create new */
if (res == FR_NO_FILE) /* There is no file to open, create a new entry */
#if _FS_SHARE
res = enq_lock() ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES;
#else
res = dir_register(&dj);
#endif
mode |= FA_CREATE_ALWAYS; /* File is created */
dir = dj.dir; /* New entry */
}
else { /* Any object is already existing */
if (dir[DIR_Attr] & (AM_RDO | AM_DIR)) { /* Cannot overwrite it (R/O or DIR) */
res = FR_DENIED;
} else {
if (mode & FA_CREATE_NEW) /* Cannot create as new file */
res = FR_EXIST;
}
}
if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) { /* Truncate it if overwrite mode */
dw = get_fattime(); /* Created time */
ST_DWORD(dir+DIR_CrtTime, dw);
dir[DIR_Attr] = 0; /* Reset attribute */
ST_DWORD(dir+DIR_FileSize, 0); /* size = 0 */
cl = LD_CLUST(dir); /* Get start cluster */
ST_CLUST(dir, 0); /* cluster = 0 */
dj.fs->wflag = 1;
if (cl) { /* Remove the cluster chain if exist */
dw = dj.fs->winsect;
res = remove_chain(dj.fs, cl);
if (res == FR_OK) {
dj.fs->last_clust = cl - 1; /* Reuse the cluster hole */
res = move_window(dj.fs, dw);
}
}
}
}
else { /* Open an existing file */
if (res == FR_OK) { /* Follow succeeded */
if (dir[DIR_Attr] & AM_DIR) { /* It is a directory */
res = FR_NO_FILE;
} else {
if ((mode & FA_WRITE) && (dir[DIR_Attr] & AM_RDO)) /* R/O violation */
res = FR_DENIED;
}
}
}
if (res == FR_OK) {
if (mode & FA_CREATE_ALWAYS) /* Set file change flag if created or overwritten */
mode |= FA__WRITTEN;
fp->dir_sect = dj.fs->winsect; /* Pointer to the directory entry */
fp->dir_ptr = dir;
#if _FS_SHARE
fp->lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0);
if (!fp->lockid) res = FR_INT_ERR;
#endif
}
#else /* R/O configuration */
if (res == FR_OK) { /* Follow succeeded */
if (!dir) { /* Current dir itself */
res = FR_INVALID_NAME;
} else {
if (dir[DIR_Attr] & AM_DIR) /* It is a directory */
res = FR_NO_FILE;
}
}
#endif
FREE_BUF();
if (res == FR_OK) {
fp->flag = mode; /* File access mode */
fp->sclust = LD_CLUST(dir); /* File start cluster */
fp->fsize = LD_DWORD(dir+DIR_FileSize); /* File size */
fp->fptr = 0; /* File pointer */
fp->dsect = 0;
#if _USE_FASTSEEK
fp->cltbl = 0; /* Normal seek mode */
#endif
fp->fs = dj.fs; fp->id = dj.fs->id; /* Validate file object */
}
LEAVE_FF(dj.fs, res);
}
2020-07-29 09:50 AM
Hi,
Just a 2 cents comment.
Using the FatFs with external Flash is not really recommended, because FatFs doesn't manage either wear leveling or bad blocks.Thus you may get you flash quickly damaged. So If you don't have any particular constraint for using FatFs I'd suggest the littlefs as a better alternative.
regards
Haithem.
2020-07-29 10:39 AM
Agreed
If it is done with NOR FLASH (QSPI or whatever) it will also write very slowly.
For a chip down implementation eMMC would be the ticket.
2020-07-29 10:44 AM
Shouldn't need to change any FATFS source, just ff_conf.h
I've got confidence in that. I would observe interaction at a sector/block level at the interface in DISKIO
The empty media would need formatting.
2020-07-29 11:05 AM
I Also recommend you to use littlefs. It has facilities for wear leveling and is fail safe (robust against power loss). littlefs library can be added to your project very easy. You just need 2 files to include.
Also take a look at SPIFFS library.
2020-07-29 08:56 PM
I've change sector size in ff_conf.h and reading sector size as 4096 from diskioctl function
#define _MAX_SS 4096 /* 512, 1024, 2048 or 4096 */
as I'm creating both files in 0:/ that's why its assigning same sector no?
shall I create file 1 in 0:/ and file 2 in 1:/ but in this case I'll have to change no of volumes in ff_conf.h?
#define _VOLUMES 1
2020-07-29 08:57 PM
thanks for your valuable input...will look into littlefs library