📄 landzo
字号:
{
for (i = 0; i < _FS_SHARE && Files[i].fs; i++) ;
if (i == _FS_SHARE) return 0; /* No space to register (int err) */
Files[i].fs = dj->fs;
Files[i].clu = dj->sclust;
Files[i].idx = dj->index;
Files[i].ctr = 0;
}
if (acc && Files[i].ctr) return 0; /* Access violation (int err) */
Files[i].ctr = acc ? 0x100 : Files[i].ctr + 1; /* Set semaphore value */
return i + 1;
}
static
FRESULT dec_lock ( /* Decrement file open counter */
UINT i /* Semaphore index */
)
{
WORD n;
FRESULT res;
if (--i < _FS_SHARE)
{
n = Files[i].ctr;
if (n == 0x100) n = 0;
if (n) n--;
Files[i].ctr = n;
if (!n) Files[i].fs = 0;
res = FR_OK;
}
else
{
res = FR_INT_ERR;
}
return res;
}
static
void clear_lock ( /* Clear lock entries of the volume */
FATFS *fs
)
{
UINT i;
for (i = 0; i < _FS_SHARE; i++)
{
if (Files[i].fs == fs) Files[i].fs = 0;
}
}
#endif
/*-----------------------------------------------------------------------*/
/* Change window offset */
/*-----------------------------------------------------------------------*/
static
FRESULT move_window (
FATFS *fs, /* File system object */
DWORD sector /* Sector number to make appearance in the fs->win[] */
) /* Move to zero only writes back dirty window */
{
DWORD wsect;
wsect = fs->winsect;
if (wsect != sector) /* Changed current window */
{
#if !_FS_READONLY
if (fs->wflag) /* Write back dirty window if needed */
{
if (disk_write(fs->drv, fs->win, wsect, 1) != RES_OK)
return FR_DISK_ERR;
fs->wflag = 0;
if (wsect < (fs->fatbase + fs->fsize)) /* In FAT area */
{
BYTE nf;
for (nf = fs->n_fats; nf > 1; nf--) /* Reflect the change to all FAT copies */
{
wsect += fs->fsize;
disk_write(fs->drv, fs->win, wsect, 1);
}
}
}
#endif
if (sector)
{
if (disk_read(fs->drv, fs->win, sector, 1) != RES_OK)
return FR_DISK_ERR;
fs->winsect = sector;
}
}
return FR_OK;
}
/*-----------------------------------------------------------------------*/
/* Clean-up cached data */
/*-----------------------------------------------------------------------*/
#if !_FS_READONLY
static
FRESULT sync ( /* FR_OK: successful, FR_DISK_ERR: failed */
FATFS *fs /* File system object */
)
{
FRESULT res;
res = move_window(fs, 0);
if (res == FR_OK)
{
/* Update FSInfo sector if needed */
if (fs->fs_type == FS_FAT32 && fs->fsi_flag)
{
fs->winsect = 0;
/* Create FSInfo structure */
mem_set(fs->win, 0, 512);
ST_WORD(fs->win + BS_55AA, 0xAA55);
ST_DWORD(fs->win + FSI_LeadSig, 0x41615252);
ST_DWORD(fs->win + FSI_StrucSig, 0x61417272);
ST_DWORD(fs->win + FSI_Free_Count, fs->free_clust);
ST_DWORD(fs->win + FSI_Nxt_Free, fs->last_clust);
/* Write it into the FSInfo sector */
disk_write(fs->drv, fs->win, fs->fsi_sector, 1);
fs->fsi_flag = 0;
}
/* Make sure that no pending write process in the physical drive */
if (disk_ioctl(fs->drv, CTRL_SYNC, 0) != RES_OK)
res = FR_DISK_ERR;
}
return res;
}
#endif
/*-----------------------------------------------------------------------*/
/* Get sector# from cluster# */
/*-----------------------------------------------------------------------*/
DWORD clust2sect ( /* !=0: Sector number, 0: Failed - invalid cluster# */
FATFS *fs, /* File system object */
DWORD clst /* Cluster# to be converted */
)
{
clst -= 2;
if (clst >= (fs->n_fatent - 2)) return 0; /* Invalid cluster# */
return clst * fs->csize + fs->database;
}
/*-----------------------------------------------------------------------*/
/* FAT access - Read value of a FAT entry */
/*-----------------------------------------------------------------------*/
DWORD get_fat ( /* 0xFFFFFFFF:Disk error, 1:Internal error, Else:Cluster status */
FATFS *fs, /* File system object */
DWORD clst /* Cluster# to get the link information */
)
{
UINT wc, bc;
BYTE *p;
if (clst < 2 || clst >= fs->n_fatent) /* Chack range */
return 1;
switch (fs->fs_type)
{
case FS_FAT12 :
bc = (UINT)clst;
bc += bc / 2;
if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break;
wc = fs->win[bc % SS(fs)];
bc++;
if (move_window(fs, fs->fatbase + (bc / SS(fs)))) break;
wc |= fs->win[bc % SS(fs)] << 8;
return (clst & 1) ? (wc >> 4) : (wc & 0xFFF);
case FS_FAT16 :
if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)))) break;
p = &fs->win[clst * 2 % SS(fs)];
return LD_WORD(p);
case FS_FAT32 :
if (move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)))) break;
p = &fs->win[clst * 4 % SS(fs)];
return LD_DWORD(p) & 0x0FFFFFFF;
}
return 0xFFFFFFFF; /* An error occurred at the disk I/O layer */
}
/*-----------------------------------------------------------------------*/
/* FAT access - Change value of a FAT entry */
/*-----------------------------------------------------------------------*/
#if !_FS_READONLY
FRESULT put_fat (
FATFS *fs, /* File system object */
DWORD clst, /* Cluster# to be changed in range of 2 to fs->n_fatent - 1 */
DWORD val /* New value to mark the cluster */
)
{
UINT bc;
BYTE *p;
FRESULT res;
if (clst < 2 || clst >= fs->n_fatent) /* Check range */
{
res = FR_INT_ERR;
}
else
{
switch (fs->fs_type)
{
case FS_FAT12 :
bc = clst;
bc += bc / 2;
res = move_window(fs, fs->fatbase + (bc / SS(fs)));
if (res != FR_OK) break;
p = &fs->win[bc % SS(fs)];
*p = (clst & 1) ? ((*p & 0x0F) | ((BYTE)val << 4)) : (BYTE)val;
bc++;
fs->wflag = 1;
res = move_window(fs, fs->fatbase + (bc / SS(fs)));
if (res != FR_OK) break;
p = &fs->win[bc % SS(fs)];
*p = (clst & 1) ? (BYTE)(val >> 4) : ((*p & 0xF0) | ((BYTE)(val >> 8) & 0x0F));
break;
case FS_FAT16 :
res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 2)));
if (res != FR_OK) break;
p = &fs->win[clst * 2 % SS(fs)];
ST_WORD(p, (WORD)val);
break;
case FS_FAT32 :
res = move_window(fs, fs->fatbase + (clst / (SS(fs) / 4)));
if (res != FR_OK) break;
p = &fs->win[clst * 4 % SS(fs)];
val |= LD_DWORD(p) & 0xF0000000;
ST_DWORD(p, val);
break;
default :
res = FR_INT_ERR;
}
fs->wflag = 1;
}
return res;
}
#endif /* !_FS_READONLY */
/*-----------------------------------------------------------------------*/
/* FAT handling - Remove a cluster chain */
/*-----------------------------------------------------------------------*/
#if !_FS_READONLY
static
FRESULT remove_chain (
FATFS *fs, /* File system object */
DWORD clst /* Cluster# to remove a chain from */
)
{
FRESULT res;
DWORD nxt;
#if _USE_ERASE
DWORD scl = clst, ecl = clst, resion[2];
#endif
if (clst < 2 || clst >= fs->n_fatent) /* Check range */
{
res = FR_INT_ERR;
}
else
{
res = FR_OK;
while (clst < fs->n_fatent) /* Not a last link? */
{
nxt = get_fat(fs, clst); /* Get cluster status */
if (nxt == 0) break; /* Empty cluster? */
if (nxt == 1)
{
res = FR_INT_ERR; /* Internal error? */
break;
}
if (nxt == 0xFFFFFFFF)
{
res = FR_DISK_ERR; /* Disk error? */
break;
}
res = put_fat(fs, clst, 0); /* Mark the cluster "empty" */
if (res != FR_OK) break;
if (fs->free_clust != 0xFFFFFFFF) /* Update FSInfo */
{
fs->free_clust++;
fs->fsi_flag = 1;
}
#if _USE_ERASE
if (ecl + 1 == nxt) /* Next cluster is contiguous */
{
ecl = nxt;
}
else /* End of contiguous clusters */
{
resion[0] = clust2sect(fs, scl); /* Start sector */
resion[1] = clust2sect(fs, ecl) + fs->csize - 1; /* End sector */
disk_ioctl(fs->drv, CTRL_ERASE_SECTOR, resion); /* Erase the block */
scl = ecl = nxt;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -