📄 ff.c
字号:
FATFS *fs = fp->fs; res = validate(fs, fp->id); /* Check validity of the object */ if (res == FR_OK) { if (fp->flag & FA__WRITTEN) { /* Has the file been written? */ /* Write back data buffer if needed */ if (fp->flag & FA__DIRTY) { if (diskWrite(fs->drive, fp->buffer, fp->curr_sect, 1) != DRESULT_OK) return FR_RW_ERROR; fp->flag &= ~FA__DIRTY; } /* Update the directory entry */ if (!move_window(fs, fp->dir_sect)) return FR_RW_ERROR; dir = fp->dir_ptr; dir[DIR_Attr] |= AM_ARC; /* Set archive bit */ ST_U32(&dir[DIR_FileSize], fp->fsize); /* Update file size */ ST_U16(&dir[DIR_FstClusLO], fp->org_clust); /* Update start cluster */ ST_U16(&dir[DIR_FstClusHI], fp->org_clust >> 16); tim = get_fattime(); /* Updated time */ ST_U32(&dir[DIR_WrtTime], tim); fp->flag &= ~FA__WRITTEN; res = sync(fs); } } return res;}#endif /* !_FS_READONLY *//*-----------------------------------------------------------------------*//* Close File *//*-----------------------------------------------------------------------*/FRESULT f_close ( FIL *fp /* Pointer to the file object to be closed */ ){ FRESULT res;#if !_FS_READONLY res = f_sync(fp);#else res = validate(fp->fs, fp->id);#endif if (res == FR_OK) fp->fs = NULL; return res;}#if _FS_MINIMIZE <= 2/*-----------------------------------------------------------------------*//* Seek File R/W Pointer *//*-----------------------------------------------------------------------*/FRESULT f_lseek ( FIL *fp, /* Pointer to the file object */ U32 ofs /* File pointer from top of file */ ){ U32 clust, csize; U8 csect; FRESULT res; FATFS *fs = fp->fs; res = validate(fs, fp->id); /* Check validity of the object */ if (res) return res; if (fp->flag & FA__ERROR) return FR_RW_ERROR;#if !_FS_READONLY if (fp->flag & FA__DIRTY) { /* Write-back dirty buffer if needed */ if (diskWrite(fs->drive, fp->buffer, fp->curr_sect, 1) != DRESULT_OK) goto fk_error; fp->flag &= ~FA__DIRTY; } if (ofs > fp->fsize && !(fp->flag & FA_WRITE))#else if (ofs > fp->fsize)#endif ofs = fp->fsize; fp->fptr = 0; fp->sect_clust = 1; /* Set file R/W pointer to top of the file */ /* Move file R/W pointer if needed */ if (ofs) { clust = fp->org_clust; /* Get start cluster */#if !_FS_READONLY if (!clust) { /* If the file does not have a cluster chain, create new cluster chain */ clust = create_chain(fs, 0); if (clust == 1) goto fk_error; fp->org_clust = clust; }#endif if (clust) { /* If the file has a cluster chain, it can be followed */ csize = (U32)fs->sects_clust * S_SIZ; /* Cluster size in unit of byte */ for (;;) { /* Loop to skip leading clusters */ fp->curr_clust = clust; /* Update current cluster */ if (ofs <= csize) break;#if !_FS_READONLY if (fp->flag & FA_WRITE) /* Check if in write mode or not */ clust = create_chain(fs, clust); /* Force streached if in write mode */ else#endif clust = get_cluster(fs, clust); /* Only follow cluster chain if not in write mode */ if (clust == 0) { /* Stop if could not follow the cluster chain */ ofs = csize; break; } if (clust == 1 || clust >= fs->max_clust) goto fk_error; fp->fptr += csize; /* Update R/W pointer */ ofs -= csize; } csect = (U8)((ofs - 1) / S_SIZ); /* Sector offset in the cluster */ fp->curr_sect = clust2sect(fs, clust) + csect; /* Current sector */ if ((ofs & (S_SIZ - 1)) && /* Load current sector if needed */ diskRead(fs->drive, fp->buffer, fp->curr_sect, 1) != DRESULT_OK) goto fk_error; fp->sect_clust = fs->sects_clust - csect; /* Left sector counter in the cluster */ fp->fptr += ofs; /* Update file R/W pointer */ } }#if !_FS_READONLY if ((fp->flag & FA_WRITE) && fp->fptr > fp->fsize) { /* Set updated flag if in write mode */ fp->fsize = fp->fptr; fp->flag |= FA__WRITTEN; }#endif return FR_OK;fk_error: /* Abort this file due to an unrecoverable error */ fp->flag |= FA__ERROR; return FR_RW_ERROR;}#if _FS_MINIMIZE <= 1/*-----------------------------------------------------------------------*//* Create a directroy object *//*-----------------------------------------------------------------------*/FRESULT f_opendir ( DIR *dirobj, /* Pointer to directory object to create */ const char *path /* Pointer to the directory path */ ){ U8 *dir; char fn[8+3+1]; FRESULT res; FATFS *fs; res = auto_mount(&path, &fs, 0); if (res != FR_OK) return res; dirobj->fs = fs; res = trace_path(dirobj, fn, path, &dir); /* Trace the directory path */ if (res == FR_OK) { /* Trace completed */ if (dir != NULL) { /* It is not the root dir */ if (dir[DIR_Attr] & AM_DIR) { /* The entry is a directory */ dirobj->clust = ((U32)LD_U16(&dir[DIR_FstClusHI]) << 16) | LD_U16(&dir[DIR_FstClusLO]); dirobj->sect = clust2sect(fs, dirobj->clust); dirobj->index = 2; } else { /* The entry is not a directory */ res = FR_NO_FILE; } } dirobj->id = fs->id; } return res;}/*-----------------------------------------------------------------------*//* Read Directory Entry in Sequense *//*-----------------------------------------------------------------------*/FRESULT f_readdir ( DIR *dirobj, /* Pointer to the directory object */ FILINFO *finfo /* Pointer to file information to return */ ){ U8 *dir, c, res; FATFS *fs = dirobj->fs; res = validate(fs, dirobj->id); /* Check validity of the object */ if (res) return (FRESULT) res; finfo->fname[0] = 0; while (dirobj->sect) { if (!move_window(fs, dirobj->sect)) return FR_RW_ERROR; dir = &fs->win[(dirobj->index & ((S_SIZ - 1) >> 5)) * 32]; /* pointer to the directory entry */ c = *dir; if (c == 0) break; /* Has it reached to end of dir? */ if (c != 0xE5 && !(dir[DIR_Attr] & AM_VOL)) /* Is it a valid entry? */ get_fileinfo(finfo, dir); if (!next_dir_entry(dirobj)) dirobj->sect = 0; /* Next entry */ if (finfo->fname[0]) break; /* Found valid entry */ } return FR_OK;}#if _FS_MINIMIZE == 0/*-----------------------------------------------------------------------*//* Get File Status *//*-----------------------------------------------------------------------*/FRESULT f_stat ( const char *path, /* Pointer to the file path */ FILINFO *finfo /* Pointer to file information to return */ ){ U8 *dir; char fn[8+3+1]; FRESULT res; DIR dirobj; FATFS *fs; res = auto_mount(&path, &fs, 0); if (res != FR_OK) return res; dirobj.fs = fs; res = trace_path(&dirobj, fn, path, &dir); /* Trace the file path */ if (res == FR_OK) { /* Trace completed */ if (dir) /* Found an object */ get_fileinfo(finfo, dir); else /* It is root dir */ res = FR_INVALID_NAME; } return res;}#if !_FS_READONLY/*-----------------------------------------------------------------------*//* Get Number of Free Clusters *//*-----------------------------------------------------------------------*/FRESULT f_getfree ( const char *drv, /* Logical drive number */ U32 *nclust, /* Pointer to the double word to return number of free clusters */ FATFS **fatfs /* Pointer to pointer to the file system object to return */ ){ U32 n, clust, sect; U8 fat, f, *p; FRESULT res; FATFS *fs; /* Get drive number */ res = auto_mount(&drv, &fs, 0); if (res != FR_OK) return res; *fatfs = fs; /* If number of free cluster is valid, return it without cluster scan. */ if (fs->free_clust <= fs->max_clust - 2) { *nclust = fs->free_clust; return FR_OK; } /* Count number of free clusters */ fat = fs->fs_type; n = 0; if (fat == FS_FAT12) { clust = 2; do { if ((U16)get_cluster(fs, clust) == 0) n++; } while (++clust < fs->max_clust); } else { clust = fs->max_clust; sect = fs->fatbase; f = 0; p = 0; do { if (!f) { if (!move_window(fs, sect++)) return FR_RW_ERROR; p = fs->win; } if (fat == FS_FAT16) { if (LD_U16(p) == 0) n++; p += 2; f += 1; } else { if (LD_U32(p) == 0) n++; p += 4; f += 2; } } while (--clust); } fs->free_clust = n;#if _USE_FSINFO if (fat == FS_FAT32) fs->fsi_flag = 1;#endif *nclust = n; return FR_OK;}/*-----------------------------------------------------------------------*//* Delete a File or a Directory *//*-----------------------------------------------------------------------*/FRESULT f_unlink ( const char *path /* Pointer to the file or directory path */ ){ U8 *dir, *sdir; U32 dclust, dsect; char fn[8+3+1]; FRESULT res; DIR dirobj; FATFS *fs; res = auto_mount(&path, &fs, 1); if (res != FR_OK) return res; dirobj.fs = fs; res = trace_path(&dirobj, fn, path, &dir); /* Trace the file path */ if (res != FR_OK) return res; /* Trace failed */ if (dir == NULL) return FR_INVALID_NAME; /* It is the root directory */ if (dir[DIR_Attr] & AM_RDO) return FR_DENIED; /* It is a R/O object */ dsect = fs->winsect; dclust = ((U32)LD_U16(&dir[DIR_FstClusHI]) << 16) | LD_U16(&dir[DIR_FstClusLO]); if (dir[DIR_Attr] & AM_DIR) { /* It is a sub-directory */ dirobj.clust = dclust; /* Check if the sub-dir is empty or not */ dirobj.sect = clust2sect(fs, dclust); dirobj.index = 2; do { if (!move_window(fs, dirobj.sect)) return FR_RW_ERROR; sdir = &fs->win[(dirobj.index & ((S_SIZ - 1) >> 5)) * 32]; if (sdir[DIR_Name] == 0) break; if (sdir[DIR_Name] != 0xE5 && !(sdir[DIR_Attr] & AM_VOL)) return FR_DENIED; /* The directory is not empty */ } while (next_dir_entry(&dirobj)); } if (!move_window(fs, dsect)) return FR_RW_ERROR; /* Mark the directory entry 'deleted' */ dir[DIR_Name] = 0xE5; fs->winflag = 1; if (!remove_chain(fs, dclust)) return FR_RW_ERROR; /* Remove the cluster chain */ return sync(fs);}/*-----------------------------------------------------------------------*//* Create a Directory *//*-----------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -