Skip to content

Commit

Permalink
FATFS patch applied, On the exFAT volume, new cluster allocation for …
Browse files Browse the repository at this point in the history
…directory fails with FR_INT_ERR.
  • Loading branch information
ClusterM committed Jul 31, 2023
1 parent 056f588 commit db3b71d
Show file tree
Hide file tree
Showing 6 changed files with 86 additions and 74 deletions.
2 changes: 1 addition & 1 deletion FdsKey/Core/Inc/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ extern "C" {
/* USER CODE BEGIN EM */
#define FDSKEY_VERION_MAJOR 1
#define FDSKEY_VERION_MINOR 1
#define FDSKEY_VERION_SUFFIX 'c'
#define FDSKEY_VERION_SUFFIX 'd'
/* USER CODE END EM */

void HAL_TIM_MspPostInit(TIM_HandleTypeDef *htim);
Expand Down
2 changes: 1 addition & 1 deletion FdsKey/Core/Src/servicemenu.c
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ uint8_t sd_format()
show_message("Formatting...", 0);
// unmount
f_mount(0, "", 1);
fr = f_mkfs("", FM_FAT | FM_FAT32 | FM_SFD, 0, work, sizeof(work));
fr = f_mkfs("", FM_ANY | FM_SFD, 0, work, sizeof(work));
if (fr != FR_OK)
{
show_error_screen_fr(fr, 0);
Expand Down
76 changes: 41 additions & 35 deletions FdsKey/Middlewares/Third_Party/FatFs/src/ff.c
Original file line number Diff line number Diff line change
Expand Up @@ -1251,8 +1251,6 @@ FRESULT fill_last_frag (
{
FRESULT res;

return FR_OK; // this function is buggy :( Seems like everything works without it.

while (obj->n_frag > 0) { /* Create the last chain on the FAT */
res = put_fat(obj->fs, lcl - obj->n_frag + 1, (obj->n_frag > 1) ? lcl - obj->n_frag + 2 : term);
if (res != FR_OK) return res;
Expand Down Expand Up @@ -1334,8 +1332,22 @@ FRESULT remove_chain ( /* FR_OK(0):succeeded, !=0:error */
if (pclst == 0) { /* Does the object have no chain? */
obj->stat = 0; /* Change the object status 'initial' */
} else {
if (obj->stat == 3 && pclst >= obj->sclust && pclst <= obj->sclust + obj->n_cont) { /* Did the chain get contiguous? */
obj->stat = 2; /* Change the object status 'contiguous' */
if (obj->stat == 0) { /* Is it a fragmented chain from the beginning of this session? */
clst = obj->sclust; /* Follow the chain to check if it gets contiguous */
while (clst != pclst) {
nxt = get_fat(obj, clst);
if (nxt < 2) return FR_INT_ERR;
if (nxt == 0xFFFFFFFF) return FR_DISK_ERR;
if (nxt != clst + 1) break; /* Not contiguous? */
clst++;
}
if (clst == pclst) { /* Has the chain got contiguous again? */
obj->stat = 2; /* Change the chain status 'contiguous' */
}
} else {
if (obj->stat == 3 && pclst >= obj->sclust && pclst <= obj->sclust + obj->n_cont) { /* Was the chain fragmented in this session and got contiguous again? */
obj->stat = 2; /* Change the chain status 'contiguous' */
}
}
}
}
Expand Down Expand Up @@ -2027,7 +2039,7 @@ FRESULT load_xdir ( /* FR_INT_ERR: invalid entry block */
/* exFAT: Load the object's directory entry block */
/*------------------------------------------------*/
static
FRESULT load_obj_dir (
FRESULT load_obj_dir (
DIR* dp, /* Blank directory object to be used to access containing direcotry */
const _FDID* obj /* Object with its containing directory information */
)
Expand All @@ -2039,6 +2051,7 @@ FRESULT load_obj_dir (
dp->obj.sclust = obj->c_scl;
dp->obj.stat = (BYTE)obj->c_size;
dp->obj.objsize = obj->c_size & 0xFFFFFF00;
dp->obj.n_frag = 0;
dp->blk_ofs = obj->c_ofs;

res = dir_sdi(dp, dp->blk_ofs); /* Goto object's entry block */
Expand Down Expand Up @@ -2314,19 +2327,22 @@ FRESULT dir_register ( /* FR_OK:succeeded, FR_DENIED:no free entry or too many S
if (res != FR_OK) return res;
dp->blk_ofs = dp->dptr - SZDIRE * (nent - 1); /* Set the allocated entry block offset */

if (dp->obj.sclust != 0 && (dp->obj.stat & 4)) { /* Has the sub-directory been stretched? */
dp->obj.objsize += (DWORD)fs->csize * SS(fs); /* Increase the directory size by cluster size */
res = fill_first_frag(&dp->obj); /* Fill first fragment on the FAT if needed */
if (res != FR_OK) return res;
res = fill_last_frag(&dp->obj, dp->clust, 0xFFFFFFFF); /* Fill last fragment on the FAT if needed */
if (dp->obj.stat & 4) { /* Has the directory been stretched? */
dp->obj.stat &= ~4;
res = fill_first_frag(&dp->obj); /* Fill the first fragment on the FAT if needed */
if (res != FR_OK) return res;
res = load_obj_dir(&dj, &dp->obj); /* Load the object status */
if (res != FR_OK) return res;
st_qword(fs->dirbuf + XDIR_FileSize, dp->obj.objsize); /* Update the allocation status */
st_qword(fs->dirbuf + XDIR_ValidFileSize, dp->obj.objsize);
fs->dirbuf[XDIR_GenFlags] = dp->obj.stat | 1;
res = store_xdir(&dj); /* Store the object status */
res = fill_last_frag(&dp->obj, dp->clust, 0xFFFFFFFF); /* Fill the last fragment on the FAT if needed */
if (res != FR_OK) return res;
if (dp->obj.sclust != 0) { /* Is it a sub directory? */
res = load_obj_dir(&dj, &dp->obj); /* Load the object status */
if (res != FR_OK) return res;
dp->obj.objsize += (DWORD)fs->csize * SS(fs); /* Increase the directory size by cluster size */
st_qword(fs->dirbuf + XDIR_FileSize, dp->obj.objsize); /* Update the allocation status */
st_qword(fs->dirbuf + XDIR_ValidFileSize, dp->obj.objsize);
fs->dirbuf[XDIR_GenFlags] = dp->obj.stat | 1;
res = store_xdir(&dj); /* Store the object status */
if (res != FR_OK) return res;
}
}

create_xdir(fs->dirbuf, fs->lfnbuf); /* Create on-memory directory block to be written later */
Expand Down Expand Up @@ -3220,27 +3236,16 @@ FRESULT validate ( /* Returns FR_OK or FR_INVALID_OBJECT */
FATFS** fs /* Pointer to pointer to the owner file system object to return */
)
{
FRESULT res = FR_INVALID_OBJECT;

FRESULT res;

if (obj && obj->fs && obj->fs->fs_type && obj->id == obj->fs->id) { /* Test if the object is valid */
#if _FS_REENTRANT
if (lock_fs(obj->fs)) { /* Obtain the filesystem object */
if (!(disk_status(obj->fs->drv) & STA_NOINIT)) { /* Test if the phsical drive is kept initialized */
res = FR_OK;
} else {
unlock_fs(obj->fs, FR_OK);
}
} else {
res = FR_TIMEOUT;
}
#else
if (!(disk_status(obj->fs->drv) & STA_NOINIT)) { /* Test if the phsical drive is kept initialized */
res = FR_OK;
}
#endif
if (!obj || !obj->fs || !obj->fs->fs_type || obj->fs->id != obj->id || (disk_status(obj->fs->drv) & STA_NOINIT)) {
*fs = 0;
res = FR_INVALID_OBJECT; /* The object is invalid */
} else {
*fs = obj->fs; /* Owner file sytem object */
ENTER_FF(obj->fs); /* Lock file system */
res = FR_OK; /* Valid object */
}
*fs = (res == FR_OK) ? obj->fs : 0; /* Corresponding filesystem object */
return res;
}

Expand Down Expand Up @@ -3452,6 +3457,7 @@ FRESULT f_open (
fp->obj.sclust = ld_dword(fs->dirbuf + XDIR_FstClus); /* Get object allocation info */
fp->obj.objsize = ld_qword(fs->dirbuf + XDIR_FileSize);
fp->obj.stat = fs->dirbuf[XDIR_GenFlags] & 2;
fp->obj.n_frag = 0;
} else
#endif
{
Expand Down
2 changes: 1 addition & 1 deletion FdsKey/Middlewares/Third_Party/FatFs/src/ff.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ typedef struct {
WORD ftime; /* Modified time */
BYTE fattrib; /* File attribute */
#if _USE_LFN != 0
TCHAR altname[13]; /* Alternative file name */
TCHAR altname[13]; /* Altenative file name */
TCHAR fname[_MAX_LFN + 1]; /* Primary file name */
#else
TCHAR fname[13]; /* File name */
Expand Down
76 changes: 41 additions & 35 deletions FdsKey_bootloader/Middlewares/Third_Party/FatFs/src/ff.c
Original file line number Diff line number Diff line change
Expand Up @@ -1251,8 +1251,6 @@ FRESULT fill_last_frag (
{
FRESULT res;

return FR_OK; // this function is buggy :( Seems like everything works without it.

while (obj->n_frag > 0) { /* Create the last chain on the FAT */
res = put_fat(obj->fs, lcl - obj->n_frag + 1, (obj->n_frag > 1) ? lcl - obj->n_frag + 2 : term);
if (res != FR_OK) return res;
Expand Down Expand Up @@ -1334,8 +1332,22 @@ FRESULT remove_chain ( /* FR_OK(0):succeeded, !=0:error */
if (pclst == 0) { /* Does the object have no chain? */
obj->stat = 0; /* Change the object status 'initial' */
} else {
if (obj->stat == 3 && pclst >= obj->sclust && pclst <= obj->sclust + obj->n_cont) { /* Did the chain get contiguous? */
obj->stat = 2; /* Change the object status 'contiguous' */
if (obj->stat == 0) { /* Is it a fragmented chain from the beginning of this session? */
clst = obj->sclust; /* Follow the chain to check if it gets contiguous */
while (clst != pclst) {
nxt = get_fat(obj, clst);
if (nxt < 2) return FR_INT_ERR;
if (nxt == 0xFFFFFFFF) return FR_DISK_ERR;
if (nxt != clst + 1) break; /* Not contiguous? */
clst++;
}
if (clst == pclst) { /* Has the chain got contiguous again? */
obj->stat = 2; /* Change the chain status 'contiguous' */
}
} else {
if (obj->stat == 3 && pclst >= obj->sclust && pclst <= obj->sclust + obj->n_cont) { /* Was the chain fragmented in this session and got contiguous again? */
obj->stat = 2; /* Change the chain status 'contiguous' */
}
}
}
}
Expand Down Expand Up @@ -2027,7 +2039,7 @@ FRESULT load_xdir ( /* FR_INT_ERR: invalid entry block */
/* exFAT: Load the object's directory entry block */
/*------------------------------------------------*/
static
FRESULT load_obj_dir (
FRESULT load_obj_dir (
DIR* dp, /* Blank directory object to be used to access containing direcotry */
const _FDID* obj /* Object with its containing directory information */
)
Expand All @@ -2039,6 +2051,7 @@ FRESULT load_obj_dir (
dp->obj.sclust = obj->c_scl;
dp->obj.stat = (BYTE)obj->c_size;
dp->obj.objsize = obj->c_size & 0xFFFFFF00;
dp->obj.n_frag = 0;
dp->blk_ofs = obj->c_ofs;

res = dir_sdi(dp, dp->blk_ofs); /* Goto object's entry block */
Expand Down Expand Up @@ -2314,19 +2327,22 @@ FRESULT dir_register ( /* FR_OK:succeeded, FR_DENIED:no free entry or too many S
if (res != FR_OK) return res;
dp->blk_ofs = dp->dptr - SZDIRE * (nent - 1); /* Set the allocated entry block offset */

if (dp->obj.sclust != 0 && (dp->obj.stat & 4)) { /* Has the sub-directory been stretched? */
dp->obj.objsize += (DWORD)fs->csize * SS(fs); /* Increase the directory size by cluster size */
res = fill_first_frag(&dp->obj); /* Fill first fragment on the FAT if needed */
if (res != FR_OK) return res;
res = fill_last_frag(&dp->obj, dp->clust, 0xFFFFFFFF); /* Fill last fragment on the FAT if needed */
if (dp->obj.stat & 4) { /* Has the directory been stretched? */
dp->obj.stat &= ~4;
res = fill_first_frag(&dp->obj); /* Fill the first fragment on the FAT if needed */
if (res != FR_OK) return res;
res = load_obj_dir(&dj, &dp->obj); /* Load the object status */
if (res != FR_OK) return res;
st_qword(fs->dirbuf + XDIR_FileSize, dp->obj.objsize); /* Update the allocation status */
st_qword(fs->dirbuf + XDIR_ValidFileSize, dp->obj.objsize);
fs->dirbuf[XDIR_GenFlags] = dp->obj.stat | 1;
res = store_xdir(&dj); /* Store the object status */
res = fill_last_frag(&dp->obj, dp->clust, 0xFFFFFFFF); /* Fill the last fragment on the FAT if needed */
if (res != FR_OK) return res;
if (dp->obj.sclust != 0) { /* Is it a sub directory? */
res = load_obj_dir(&dj, &dp->obj); /* Load the object status */
if (res != FR_OK) return res;
dp->obj.objsize += (DWORD)fs->csize * SS(fs); /* Increase the directory size by cluster size */
st_qword(fs->dirbuf + XDIR_FileSize, dp->obj.objsize); /* Update the allocation status */
st_qword(fs->dirbuf + XDIR_ValidFileSize, dp->obj.objsize);
fs->dirbuf[XDIR_GenFlags] = dp->obj.stat | 1;
res = store_xdir(&dj); /* Store the object status */
if (res != FR_OK) return res;
}
}

create_xdir(fs->dirbuf, fs->lfnbuf); /* Create on-memory directory block to be written later */
Expand Down Expand Up @@ -3220,27 +3236,16 @@ FRESULT validate ( /* Returns FR_OK or FR_INVALID_OBJECT */
FATFS** fs /* Pointer to pointer to the owner file system object to return */
)
{
FRESULT res = FR_INVALID_OBJECT;

FRESULT res;

if (obj && obj->fs && obj->fs->fs_type && obj->id == obj->fs->id) { /* Test if the object is valid */
#if _FS_REENTRANT
if (lock_fs(obj->fs)) { /* Obtain the filesystem object */
if (!(disk_status(obj->fs->drv) & STA_NOINIT)) { /* Test if the phsical drive is kept initialized */
res = FR_OK;
} else {
unlock_fs(obj->fs, FR_OK);
}
} else {
res = FR_TIMEOUT;
}
#else
if (!(disk_status(obj->fs->drv) & STA_NOINIT)) { /* Test if the phsical drive is kept initialized */
res = FR_OK;
}
#endif
if (!obj || !obj->fs || !obj->fs->fs_type || obj->fs->id != obj->id || (disk_status(obj->fs->drv) & STA_NOINIT)) {
*fs = 0;
res = FR_INVALID_OBJECT; /* The object is invalid */
} else {
*fs = obj->fs; /* Owner file sytem object */
ENTER_FF(obj->fs); /* Lock file system */
res = FR_OK; /* Valid object */
}
*fs = (res == FR_OK) ? obj->fs : 0; /* Corresponding filesystem object */
return res;
}

Expand Down Expand Up @@ -3452,6 +3457,7 @@ FRESULT f_open (
fp->obj.sclust = ld_dword(fs->dirbuf + XDIR_FstClus); /* Get object allocation info */
fp->obj.objsize = ld_qword(fs->dirbuf + XDIR_FileSize);
fp->obj.stat = fs->dirbuf[XDIR_GenFlags] & 2;
fp->obj.n_frag = 0;
} else
#endif
{
Expand Down
2 changes: 1 addition & 1 deletion FdsKey_bootloader/Middlewares/Third_Party/FatFs/src/ff.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ typedef struct {
WORD ftime; /* Modified time */
BYTE fattrib; /* File attribute */
#if _USE_LFN != 0
TCHAR altname[13]; /* Alternative file name */
TCHAR altname[13]; /* Altenative file name */
TCHAR fname[_MAX_LFN + 1]; /* Primary file name */
#else
TCHAR fname[13]; /* File name */
Expand Down

0 comments on commit db3b71d

Please sign in to comment.