Prusa MINI Firmware overview
ff.h File Reference
#include "integer.h"
#include "ffconf.h"

Go to the source code of this file.

Classes

struct  FATFS
 
struct  _FDID
 
struct  FIL
 
struct  DIR
 
struct  FILINFO
 

Macros

#define _FATFS   68300 /* Revision ID */
 
#define _T(x)   x
 
#define _TEXT(x)   x
 
#define f_eof(fp)   ((int)((fp)->fptr == (fp)->obj.objsize))
 
#define f_error(fp)   ((fp)->err)
 
#define f_tell(fp)   ((fp)->fptr)
 
#define f_size(fp)   ((fp)->obj.objsize)
 
#define f_rewind(fp)   f_lseek((fp), 0)
 
#define f_rewinddir(dp)   f_readdir((dp), 0)
 
#define f_rmdir(path)   f_unlink(path)
 
#define EOF   (-1)
 
#define FA_READ   0x01
 
#define FA_WRITE   0x02
 
#define FA_OPEN_EXISTING   0x00
 
#define FA_CREATE_NEW   0x04
 
#define FA_CREATE_ALWAYS   0x08
 
#define FA_OPEN_ALWAYS   0x10
 
#define FA_OPEN_APPEND   0x30
 
#define CREATE_LINKMAP   ((FSIZE_t)0 - 1)
 
#define FM_FAT   0x01
 
#define FM_FAT32   0x02
 
#define FM_EXFAT   0x04
 
#define FM_ANY   0x07
 
#define FM_SFD   0x08
 
#define FS_FAT12   1
 
#define FS_FAT16   2
 
#define FS_FAT32   3
 
#define FS_EXFAT   4
 
#define AM_RDO   0x01 /* Read only */
 
#define AM_HID   0x02 /* Hidden */
 
#define AM_SYS   0x04 /* System */
 
#define AM_DIR   0x10 /* Directory */
 
#define AM_ARC   0x20 /* Archive */
 

Typedefs

typedef char TCHAR
 
typedef DWORD FSIZE_t
 

Enumerations

enum  FRESULT {
  FR_OK = 0, FR_DISK_ERR, FR_INT_ERR, FR_NOT_READY,
  FR_NO_FILE, FR_NO_PATH, FR_INVALID_NAME, FR_DENIED,
  FR_EXIST, FR_INVALID_OBJECT, FR_WRITE_PROTECTED, FR_INVALID_DRIVE,
  FR_NOT_ENABLED, FR_NO_FILESYSTEM, FR_MKFS_ABORTED, FR_TIMEOUT,
  FR_LOCKED, FR_NOT_ENOUGH_CORE, FR_TOO_MANY_OPEN_FILES, FR_INVALID_PARAMETER
}
 

Functions

FRESULT f_open (FIL *fp, const TCHAR *path, BYTE mode)
 
FRESULT f_close (FIL *fp)
 
FRESULT f_read (FIL *fp, void *buff, UINT btr, UINT *br)
 
FRESULT f_write (FIL *fp, const void *buff, UINT btw, UINT *bw)
 
FRESULT f_lseek (FIL *fp, FSIZE_t ofs)
 
FRESULT f_truncate (FIL *fp)
 
FRESULT f_sync (FIL *fp)
 
FRESULT f_opendir (DIR *dp, const TCHAR *path)
 
FRESULT f_closedir (DIR *dp)
 
FRESULT f_readdir (DIR *dp, FILINFO *fno)
 
FRESULT f_findfirst (DIR *dp, FILINFO *fno, const TCHAR *path, const TCHAR *pattern)
 
FRESULT f_findnext (DIR *dp, FILINFO *fno)
 
FRESULT f_mkdir (const TCHAR *path)
 
FRESULT f_unlink (const TCHAR *path)
 
FRESULT f_rename (const TCHAR *path_old, const TCHAR *path_new)
 
FRESULT f_stat (const TCHAR *path, FILINFO *fno)
 
FRESULT f_chmod (const TCHAR *path, BYTE attr, BYTE mask)
 
FRESULT f_utime (const TCHAR *path, const FILINFO *fno)
 
FRESULT f_chdir (const TCHAR *path)
 
FRESULT f_chdrive (const TCHAR *path)
 
FRESULT f_getcwd (TCHAR *buff, UINT len)
 
FRESULT f_getdirpath (DIR *pd, TCHAR *buff, UINT len)
 
FRESULT f_getfree (const TCHAR *path, DWORD *nclst, FATFS **fatfs)
 
FRESULT f_getlabel (const TCHAR *path, TCHAR *label, DWORD *vsn)
 
FRESULT f_setlabel (const TCHAR *label)
 
FRESULT f_forward (FIL *fp, UINT(*func)(const BYTE *, UINT), UINT btf, UINT *bf)
 
FRESULT f_expand (FIL *fp, FSIZE_t szf, BYTE opt)
 
FRESULT f_mount (FATFS *fs, const TCHAR *path, BYTE opt)
 
FRESULT f_mkfs (const TCHAR *path, BYTE opt, DWORD au, void *work, UINT len)
 
FRESULT f_fdisk (BYTE pdrv, const DWORD *szt, void *work)
 
int f_putc (TCHAR c, FIL *fp)
 
int f_puts (const TCHAR *str, FIL *cp)
 
int f_printf (FIL *fp, const TCHAR *str,...)
 
TCHARf_gets (TCHAR *buff, int len, FIL *fp)
 
DWORD get_fattime (void)
 Gets Time from RTC. More...
 

Macro Definition Documentation

◆ _FATFS

#define _FATFS   68300 /* Revision ID */

◆ _T

#define _T (   x)    x

◆ _TEXT

#define _TEXT (   x)    x

◆ f_eof

#define f_eof (   fp)    ((int)((fp)->fptr == (fp)->obj.objsize))

◆ f_error

#define f_error (   fp)    ((fp)->err)

◆ f_tell

#define f_tell (   fp)    ((fp)->fptr)

◆ f_size

#define f_size (   fp)    ((fp)->obj.objsize)

◆ f_rewind

#define f_rewind (   fp)    f_lseek((fp), 0)

◆ f_rewinddir

#define f_rewinddir (   dp)    f_readdir((dp), 0)

◆ f_rmdir

#define f_rmdir (   path)    f_unlink(path)

◆ EOF

#define EOF   (-1)

◆ FA_READ

#define FA_READ   0x01

◆ FA_WRITE

#define FA_WRITE   0x02

◆ FA_OPEN_EXISTING

#define FA_OPEN_EXISTING   0x00

◆ FA_CREATE_NEW

#define FA_CREATE_NEW   0x04

◆ FA_CREATE_ALWAYS

#define FA_CREATE_ALWAYS   0x08

◆ FA_OPEN_ALWAYS

#define FA_OPEN_ALWAYS   0x10

◆ FA_OPEN_APPEND

#define FA_OPEN_APPEND   0x30

◆ CREATE_LINKMAP

#define CREATE_LINKMAP   ((FSIZE_t)0 - 1)

◆ FM_FAT

#define FM_FAT   0x01

◆ FM_FAT32

#define FM_FAT32   0x02

◆ FM_EXFAT

#define FM_EXFAT   0x04

◆ FM_ANY

#define FM_ANY   0x07

◆ FM_SFD

#define FM_SFD   0x08

◆ FS_FAT12

#define FS_FAT12   1

◆ FS_FAT16

#define FS_FAT16   2

◆ FS_FAT32

#define FS_FAT32   3

◆ FS_EXFAT

#define FS_EXFAT   4

◆ AM_RDO

#define AM_RDO   0x01 /* Read only */

◆ AM_HID

#define AM_HID   0x02 /* Hidden */

◆ AM_SYS

#define AM_SYS   0x04 /* System */

◆ AM_DIR

#define AM_DIR   0x10 /* Directory */

◆ AM_ARC

#define AM_ARC   0x20 /* Archive */

Typedef Documentation

◆ TCHAR

typedef char TCHAR

◆ FSIZE_t

typedef DWORD FSIZE_t

Enumeration Type Documentation

◆ FRESULT

enum FRESULT
Enumerator
FR_OK 
FR_DISK_ERR 
FR_INT_ERR 
FR_NOT_READY 
FR_NO_FILE 
FR_NO_PATH 
FR_INVALID_NAME 
FR_DENIED 
FR_EXIST 
FR_INVALID_OBJECT 
FR_WRITE_PROTECTED 
FR_INVALID_DRIVE 
FR_NOT_ENABLED 
FR_NO_FILESYSTEM 
FR_MKFS_ABORTED 
FR_TIMEOUT 
FR_LOCKED 
FR_NOT_ENOUGH_CORE 
FR_TOO_MANY_OPEN_FILES 
FR_INVALID_PARAMETER 
214  {
215  FR_OK = 0, /* (0) Succeeded */
216  FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
217  FR_INT_ERR, /* (2) Assertion failed */
218  FR_NOT_READY, /* (3) The physical drive cannot work */
219  FR_NO_FILE, /* (4) Could not find the file */
220  FR_NO_PATH, /* (5) Could not find the path */
221  FR_INVALID_NAME, /* (6) The path name format is invalid */
222  FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
223  FR_EXIST, /* (8) Access denied due to prohibited access */
224  FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
225  FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
226  FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
227  FR_NOT_ENABLED, /* (12) The volume has no work area */
228  FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
229  FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
230  FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
231  FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
232  FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
233  FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > _FS_LOCK */
234  FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
235 } FRESULT;

Function Documentation

◆ f_open()

FRESULT f_open ( FIL fp,
const TCHAR path,
BYTE  mode 
)
3301 {
3302  FRESULT res;
3303  DIR dj;
3304  FATFS *fs;
3305 #if !_FS_READONLY
3306  DWORD dw, cl, bcs, clst, sc;
3307  FSIZE_t ofs;
3308 #endif
3309  DEF_NAMBUF
3310 
3311 
3312  if (!fp) return FR_INVALID_OBJECT;
3313 
3314  /* Get logical drive */
3316  res = find_volume(&path, &fs, mode);
3317  if (res == FR_OK) {
3318  dj.obj.fs = fs;
3319  INIT_NAMBUF(fs);
3320  res = follow_path(&dj, path); /* Follow the file path */
3321 #if !_FS_READONLY /* R/W configuration */
3322  if (res == FR_OK) {
3323  if (dj.fn[NSFLAG] & NS_NONAME) { /* Origin directory itself? */
3324  res = FR_INVALID_NAME;
3325  }
3326 #if _FS_LOCK != 0
3327  else {
3328  res = chk_lock(&dj, (mode & ~FA_READ) ? 1 : 0);
3329  }
3330 #endif
3331  }
3332  /* Create or Open a file */
3334  if (res != FR_OK) { /* No file, create new */
3335  if (res == FR_NO_FILE) { /* There is no file to open, create a new entry */
3336 #if _FS_LOCK != 0
3337  res = enq_lock() ? dir_register(&dj) : FR_TOO_MANY_OPEN_FILES;
3338 #else
3339  res = dir_register(&dj);
3340 #endif
3341  }
3342  mode |= FA_CREATE_ALWAYS; /* File is created */
3343  }
3344  else { /* Any object is already existing */
3345  if (dj.obj.attr & (AM_RDO | AM_DIR)) { /* Cannot overwrite it (R/O or DIR) */
3346  res = FR_DENIED;
3347  } else {
3348  if (mode & FA_CREATE_NEW) res = FR_EXIST; /* Cannot create as new file */
3349  }
3350  }
3351  if (res == FR_OK && (mode & FA_CREATE_ALWAYS)) { /* Truncate it if overwrite mode */
3352  dw = GET_FATTIME();
3353 #if _FS_EXFAT
3354  if (fs->fs_type == FS_EXFAT) {
3355  /* Get current allocation info */
3356  fp->obj.fs = fs;
3357  fp->obj.sclust = ld_dword(fs->dirbuf + XDIR_FstClus);
3358  fp->obj.objsize = ld_qword(fs->dirbuf + XDIR_FileSize);
3359  fp->obj.stat = fs->dirbuf[XDIR_GenFlags] & 2;
3360  fp->obj.n_frag = 0;
3361  /* Initialize directory entry block */
3362  st_dword(fs->dirbuf + XDIR_CrtTime, dw); /* Set created time */
3363  fs->dirbuf[XDIR_CrtTime10] = 0;
3364  st_dword(fs->dirbuf + XDIR_ModTime, dw); /* Set modified time */
3365  fs->dirbuf[XDIR_ModTime10] = 0;
3366  fs->dirbuf[XDIR_Attr] = AM_ARC; /* Reset attribute */
3367  st_dword(fs->dirbuf + XDIR_FstClus, 0); /* Reset file allocation info */
3368  st_qword(fs->dirbuf + XDIR_FileSize, 0);
3369  st_qword(fs->dirbuf + XDIR_ValidFileSize, 0);
3370  fs->dirbuf[XDIR_GenFlags] = 1;
3371  res = store_xdir(&dj);
3372  if (res == FR_OK && fp->obj.sclust) { /* Remove the cluster chain if exist */
3373  res = remove_chain(&fp->obj, fp->obj.sclust, 0);
3374  fs->last_clst = fp->obj.sclust - 1; /* Reuse the cluster hole */
3375  }
3376  } else
3377 #endif
3378  {
3379  /* Clean directory info */
3380  st_dword(dj.dir + DIR_CrtTime, dw); /* Set created time */
3381  st_dword(dj.dir + DIR_ModTime, dw); /* Set modified time */
3382  dj.dir[DIR_Attr] = AM_ARC; /* Reset attribute */
3383  cl = ld_clust(fs, dj.dir); /* Get cluster chain */
3384  st_clust(fs, dj.dir, 0); /* Reset file allocation info */
3385  st_dword(dj.dir + DIR_FileSize, 0);
3386  fs->wflag = 1;
3387 
3388  if (cl) { /* Remove the cluster chain if exist */
3389  dw = fs->winsect;
3390  res = remove_chain(&dj.obj, cl, 0);
3391  if (res == FR_OK) {
3392  res = move_window(fs, dw);
3393  fs->last_clst = cl - 1; /* Reuse the cluster hole */
3394  }
3395  }
3396  }
3397  }
3398  }
3399  else { /* Open an existing file */
3400  if (res == FR_OK) { /* Following succeeded */
3401  if (dj.obj.attr & AM_DIR) { /* It is a directory */
3402  res = FR_NO_FILE;
3403  } else {
3404  if ((mode & FA_WRITE) && (dj.obj.attr & AM_RDO)) { /* R/O violation */
3405  res = FR_DENIED;
3406  }
3407  }
3408  }
3409  }
3410  if (res == FR_OK) {
3411  if (mode & FA_CREATE_ALWAYS) /* Set file change flag if created or overwritten */
3412  mode |= FA_MODIFIED;
3413  fp->dir_sect = fs->winsect; /* Pointer to the directory entry */
3414  fp->dir_ptr = dj.dir;
3415 #if _FS_LOCK != 0
3416  fp->obj.lockid = inc_lock(&dj, (mode & ~FA_READ) ? 1 : 0);
3417  if (!fp->obj.lockid) res = FR_INT_ERR;
3418 #endif
3419  }
3420 #else /* R/O configuration */
3421  if (res == FR_OK) {
3422  if (dj.fn[NSFLAG] & NS_NONAME) { /* Origin directory itself? */
3423  res = FR_INVALID_NAME;
3424  } else {
3425  if (dj.obj.attr & AM_DIR) { /* It is a directory */
3426  res = FR_NO_FILE;
3427  }
3428  }
3429  }
3430 #endif
3431 
3432  if (res == FR_OK) {
3433 #if _FS_EXFAT
3434  if (fs->fs_type == FS_EXFAT) {
3435  fp->obj.c_scl = dj.obj.sclust; /* Get containing directory info */
3436  fp->obj.c_size = ((DWORD)dj.obj.objsize & 0xFFFFFF00) | dj.obj.stat;
3437  fp->obj.c_ofs = dj.blk_ofs;
3438  fp->obj.sclust = ld_dword(fs->dirbuf + XDIR_FstClus); /* Get object allocation info */
3439  fp->obj.objsize = ld_qword(fs->dirbuf + XDIR_FileSize);
3440  fp->obj.stat = fs->dirbuf[XDIR_GenFlags] & 2;
3441  } else
3442 #endif
3443  {
3444  fp->obj.sclust = ld_clust(fs, dj.dir); /* Get object allocation info */
3445  fp->obj.objsize = ld_dword(dj.dir + DIR_FileSize);
3446  }
3447 #if _USE_FASTSEEK
3448  fp->cltbl = 0; /* Disable fast seek mode */
3449 #endif
3450  fp->obj.fs = fs; /* Validate the file object */
3451  fp->obj.id = fs->id;
3452  fp->flag = mode; /* Set file access mode */
3453  fp->err = 0; /* Clear error flag */
3454  fp->sect = 0; /* Invalidate current data sector */
3455  fp->fptr = 0; /* Set file pointer top of the file */
3456 #if !_FS_READONLY
3457 #if !_FS_TINY
3458  mem_set(fp->buf, 0, _MAX_SS); /* Clear sector buffer */
3459 #endif
3460  if ((mode & FA_SEEKEND) && fp->obj.objsize > 0) { /* Seek to end of file if FA_OPEN_APPEND is specified */
3461  fp->fptr = fp->obj.objsize; /* Offset to seek */
3462  bcs = (DWORD)fs->csize * SS(fs); /* Cluster size in byte */
3463  clst = fp->obj.sclust; /* Follow the cluster chain */
3464  for (ofs = fp->obj.objsize; res == FR_OK && ofs > bcs; ofs -= bcs) {
3465  clst = get_fat(&fp->obj, clst);
3466  if (clst <= 1) res = FR_INT_ERR;
3467  if (clst == 0xFFFFFFFF) res = FR_DISK_ERR;
3468  }
3469  fp->clust = clst;
3470  if (res == FR_OK && ofs % SS(fs)) { /* Fill sector buffer if not on the sector boundary */
3471  if ((sc = clust2sect(fs, clst)) == 0) {
3472  res = FR_INT_ERR;
3473  } else {
3474  fp->sect = sc + (DWORD)(ofs / SS(fs));
3475 #if !_FS_TINY
3476  if (disk_read(fs->drv, fp->buf, fp->sect, 1) != RES_OK) res = FR_DISK_ERR;
3477 #endif
3478  }
3479  }
3480  }
3481 #endif
3482  }
3483 
3484  FREE_NAMBUF();
3485  }
3486 
3487  if (res != FR_OK) fp->obj.fs = 0; /* Invalidate file object on error */
3488 
3489  LEAVE_FF(fs, res);
3490 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ f_close()

FRESULT f_close ( FIL fp)
3804 {
3805  FRESULT res;
3806  FATFS *fs;
3807 
3808 #if !_FS_READONLY
3809  res = f_sync(fp); /* Flush cached data */
3810  if (res == FR_OK)
3811 #endif
3812  {
3813  res = validate(&fp->obj, &fs); /* Lock volume */
3814  if (res == FR_OK) {
3815 #if _FS_LOCK != 0
3816  res = dec_lock(fp->obj.lockid); /* Decrement file open counter */
3817  if (res == FR_OK)
3818 #endif
3819  {
3820  fp->obj.fs = 0; /* Invalidate file object */
3821  }
3822 #if _FS_REENTRANT
3823  unlock_fs(fs, FR_OK); /* Unlock volume */
3824 #endif
3825  }
3826  }
3827  return res;
3828 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ f_read()

FRESULT f_read ( FIL fp,
void buff,
UINT  btr,
UINT br 
)
3505 {
3506  FRESULT res;
3507  FATFS *fs;
3508  DWORD clst, sect;
3509  FSIZE_t remain;
3510  UINT rcnt, cc, csect;
3511  BYTE *rbuff = (BYTE*)buff;
3512 
3513 
3514  *br = 0; /* Clear read byte counter */
3515  res = validate(&fp->obj, &fs); /* Check validity of the file object */
3516  if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */
3517  if (!(fp->flag & FA_READ)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */
3518  remain = fp->obj.objsize - fp->fptr;
3519  if (btr > remain) btr = (UINT)remain; /* Truncate btr by remaining bytes */
3520 
3521  for ( ; btr; /* Repeat until all data read */
3522  rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) {
3523  if (fp->fptr % SS(fs) == 0) { /* On the sector boundary? */
3524  csect = (UINT)(fp->fptr / SS(fs) & (fs->csize - 1)); /* Sector offset in the cluster */
3525  if (csect == 0) { /* On the cluster boundary? */
3526  if (fp->fptr == 0) { /* On the top of the file? */
3527  clst = fp->obj.sclust; /* Follow cluster chain from the origin */
3528  } else { /* Middle or end of the file */
3529 #if _USE_FASTSEEK
3530  if (fp->cltbl) {
3531  clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
3532  } else
3533 #endif
3534  {
3535  clst = get_fat(&fp->obj, fp->clust); /* Follow cluster chain on the FAT */
3536  }
3537  }
3538  if (clst < 2) ABORT(fs, FR_INT_ERR);
3539  if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
3540  fp->clust = clst; /* Update current cluster */
3541  }
3542  sect = clust2sect(fs, fp->clust); /* Get current sector */
3543  if (!sect) ABORT(fs, FR_INT_ERR);
3544  sect += csect;
3545  cc = btr / SS(fs); /* When remaining bytes >= sector size, */
3546  if (cc) { /* Read maximum contiguous sectors directly */
3547  if (csect + cc > fs->csize) { /* Clip at cluster boundary */
3548  cc = fs->csize - csect;
3549  }
3550  if (disk_read(fs->drv, rbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR);
3551 #if !_FS_READONLY && _FS_MINIMIZE <= 2 /* Replace one of the read sectors with cached data if it contains a dirty sector */
3552 #if _FS_TINY
3553  if (fs->wflag && fs->winsect - sect < cc) {
3554  mem_cpy(rbuff + ((fs->winsect - sect) * SS(fs)), fs->win, SS(fs));
3555  }
3556 #else
3557  if ((fp->flag & FA_DIRTY) && fp->sect - sect < cc) {
3558  mem_cpy(rbuff + ((fp->sect - sect) * SS(fs)), fp->buf, SS(fs));
3559  }
3560 #endif
3561 #endif
3562  rcnt = SS(fs) * cc; /* Number of bytes transferred */
3563  continue;
3564  }
3565 #if !_FS_TINY
3566  if (fp->sect != sect) { /* Load data sector if not in cache */
3567 #if !_FS_READONLY
3568  if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */
3569  if (disk_write(fs->drv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
3570  fp->flag &= (BYTE)~FA_DIRTY;
3571  }
3572 #endif
3573  if (disk_read(fs->drv, fp->buf, sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache */
3574  }
3575 #endif
3576  fp->sect = sect;
3577  }
3578  rcnt = SS(fs) - (UINT)fp->fptr % SS(fs); /* Number of bytes left in the sector */
3579  if (rcnt > btr) rcnt = btr; /* Clip it by btr if needed */
3580 #if _FS_TINY
3581  if (move_window(fs, fp->sect) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Move sector window */
3582  mem_cpy(rbuff, fs->win + fp->fptr % SS(fs), rcnt); /* Extract partial sector */
3583 #else
3584  mem_cpy(rbuff, fp->buf + fp->fptr % SS(fs), rcnt); /* Extract partial sector */
3585 #endif
3586  }
3587 
3588  LEAVE_FF(fs, FR_OK);
3589 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ f_write()

FRESULT f_write ( FIL fp,
const void buff,
UINT  btw,
UINT bw 
)
3605 {
3606  FRESULT res;
3607  FATFS *fs;
3608  DWORD clst, sect;
3609  UINT wcnt, cc, csect;
3610  const BYTE *wbuff = (const BYTE*)buff;
3611 
3612 
3613  *bw = 0; /* Clear write byte counter */
3614  res = validate(&fp->obj, &fs); /* Check validity of the file object */
3615  if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res); /* Check validity */
3616  if (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */
3617 
3618  /* Check fptr wrap-around (file size cannot reach 4GiB on FATxx) */
3619  if ((!_FS_EXFAT || fs->fs_type != FS_EXFAT) && (DWORD)(fp->fptr + btw) < (DWORD)fp->fptr) {
3620  btw = (UINT)(0xFFFFFFFF - (DWORD)fp->fptr);
3621  }
3622 
3623  for ( ; btw; /* Repeat until all data written */
3624  wbuff += wcnt, fp->fptr += wcnt, fp->obj.objsize = (fp->fptr > fp->obj.objsize) ? fp->fptr : fp->obj.objsize, *bw += wcnt, btw -= wcnt) {
3625  if (fp->fptr % SS(fs) == 0) { /* On the sector boundary? */
3626  csect = (UINT)(fp->fptr / SS(fs)) & (fs->csize - 1); /* Sector offset in the cluster */
3627  if (csect == 0) { /* On the cluster boundary? */
3628  if (fp->fptr == 0) { /* On the top of the file? */
3629  clst = fp->obj.sclust; /* Follow from the origin */
3630  if (clst == 0) { /* If no cluster is allocated, */
3631  clst = create_chain(&fp->obj, 0); /* create a new cluster chain */
3632  }
3633  } else { /* On the middle or end of the file */
3634 #if _USE_FASTSEEK
3635  if (fp->cltbl) {
3636  clst = clmt_clust(fp, fp->fptr); /* Get cluster# from the CLMT */
3637  } else
3638 #endif
3639  {
3640  clst = create_chain(&fp->obj, fp->clust); /* Follow or stretch cluster chain on the FAT */
3641  }
3642  }
3643  if (clst == 0) break; /* Could not allocate a new cluster (disk full) */
3644  if (clst == 1) ABORT(fs, FR_INT_ERR);
3645  if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
3646  fp->clust = clst; /* Update current cluster */
3647  if (fp->obj.sclust == 0) fp->obj.sclust = clst; /* Set start cluster if the first write */
3648  }
3649 #if _FS_TINY
3650  if (fs->winsect == fp->sect && sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Write-back sector cache */
3651 #else
3652  if (fp->flag & FA_DIRTY) { /* Write-back sector cache */
3653  if (disk_write(fs->drv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
3654  fp->flag &= (BYTE)~FA_DIRTY;
3655  }
3656 #endif
3657  sect = clust2sect(fs, fp->clust); /* Get current sector */
3658  if (!sect) ABORT(fs, FR_INT_ERR);
3659  sect += csect;
3660  cc = btw / SS(fs); /* When remaining bytes >= sector size, */
3661  if (cc) { /* Write maximum contiguous sectors directly */
3662  if (csect + cc > fs->csize) { /* Clip at cluster boundary */
3663  cc = fs->csize - csect;
3664  }
3665  if (disk_write(fs->drv, wbuff, sect, cc) != RES_OK) ABORT(fs, FR_DISK_ERR);
3666 #if _FS_MINIMIZE <= 2
3667 #if _FS_TINY
3668  if (fs->winsect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */
3669  mem_cpy(fs->win, wbuff + ((fs->winsect - sect) * SS(fs)), SS(fs));
3670  fs->wflag = 0;
3671  }
3672 #else
3673  if (fp->sect - sect < cc) { /* Refill sector cache if it gets invalidated by the direct write */
3674  mem_cpy(fp->buf, wbuff + ((fp->sect - sect) * SS(fs)), SS(fs));
3675  fp->flag &= (BYTE)~FA_DIRTY;
3676  }
3677 #endif
3678 #endif
3679  wcnt = SS(fs) * cc; /* Number of bytes transferred */
3680  continue;
3681  }
3682 #if _FS_TINY
3683  if (fp->fptr >= fp->obj.objsize) { /* Avoid silly cache filling on the growing edge */
3684  if (sync_window(fs) != FR_OK) ABORT(fs, FR_DISK_ERR);
3685  fs->winsect = sect;
3686  }
3687 #else
3688  if (fp->sect != sect && /* Fill sector cache with file data */
3689  fp->fptr < fp->obj.objsize &&
3690  disk_read(fs->drv, fp->buf, sect, 1) != RES_OK) {
3691  ABORT(fs, FR_DISK_ERR);
3692  }
3693 #endif
3694  fp->sect = sect;
3695  }
3696  wcnt = SS(fs) - (UINT)fp->fptr % SS(fs); /* Number of bytes left in the sector */
3697  if (wcnt > btw) wcnt = btw; /* Clip it by btw if needed */
3698 #if _FS_TINY
3699  if (move_window(fs, fp->sect) != FR_OK) ABORT(fs, FR_DISK_ERR); /* Move sector window */
3700  mem_cpy(fs->win + fp->fptr % SS(fs), wbuff, wcnt); /* Fit data to the sector */
3701  fs->wflag = 1;
3702 #else
3703  mem_cpy(fp->buf + fp->fptr % SS(fs), wbuff, wcnt); /* Fit data to the sector */
3704  fp->flag |= FA_DIRTY;
3705 #endif
3706  }
3707 
3708  fp->flag |= FA_MODIFIED; /* Set file change flag */
3709 
3710  LEAVE_FF(fs, FR_OK);
3711 }
Here is the call graph for this function:

◆ f_lseek()

FRESULT f_lseek ( FIL fp,
FSIZE_t  ofs 
)
4064 {
4065  FRESULT res;
4066  FATFS *fs;
4067  DWORD clst, bcs, nsect;
4068  FSIZE_t ifptr;
4069 #if _USE_FASTSEEK
4070  DWORD cl, pcl, ncl, tcl, dsc, tlen, ulen, *tbl;
4071 #endif
4072 
4073  res = validate(&fp->obj, &fs); /* Check validity of the file object */
4074  if (res == FR_OK) res = (FRESULT)fp->err;
4075 #if _FS_EXFAT && !_FS_READONLY
4076  if (res == FR_OK && fs->fs_type == FS_EXFAT) {
4077  res = fill_last_frag(&fp->obj, fp->clust, 0xFFFFFFFF); /* Fill last fragment on the FAT if needed */
4078  }
4079 #endif
4080  if (res != FR_OK) LEAVE_FF(fs, res);
4081 
4082 #if _USE_FASTSEEK
4083  if (fp->cltbl) { /* Fast seek */
4084  if (ofs == CREATE_LINKMAP) { /* Create CLMT */
4085  tbl = fp->cltbl;
4086  tlen = *tbl++; ulen = 2; /* Given table size and required table size */
4087  cl = fp->obj.sclust; /* Origin of the chain */
4088  if (cl) {
4089  do {
4090  /* Get a fragment */
4091  tcl = cl; ncl = 0; ulen += 2; /* Top, length and used items */
4092  do {
4093  pcl = cl; ncl++;
4094  cl = get_fat(&fp->obj, cl);
4095  if (cl <= 1) ABORT(fs, FR_INT_ERR);
4096  if (cl == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
4097  } while (cl == pcl + 1);
4098  if (ulen <= tlen) { /* Store the length and top of the fragment */
4099  *tbl++ = ncl; *tbl++ = tcl;
4100  }
4101  } while (cl < fs->n_fatent); /* Repeat until end of chain */
4102  }
4103  *fp->cltbl = ulen; /* Number of items used */
4104  if (ulen <= tlen) {
4105  *tbl = 0; /* Terminate table */
4106  } else {
4107  res = FR_NOT_ENOUGH_CORE; /* Given table size is smaller than required */
4108  }
4109  } else { /* Fast seek */
4110  if (ofs > fp->obj.objsize) ofs = fp->obj.objsize; /* Clip offset at the file size */
4111  fp->fptr = ofs; /* Set file pointer */
4112  if (ofs) {
4113  fp->clust = clmt_clust(fp, ofs - 1);
4114  dsc = clust2sect(fs, fp->clust);
4115  if (!dsc) ABORT(fs, FR_INT_ERR);
4116  dsc += (DWORD)((ofs - 1) / SS(fs)) & (fs->csize - 1);
4117  if (fp->fptr % SS(fs) && dsc != fp->sect) { /* Refill sector cache if needed */
4118 #if !_FS_TINY
4119 #if !_FS_READONLY
4120  if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */
4121  if (disk_write(fs->drv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
4122  fp->flag &= (BYTE)~FA_DIRTY;
4123  }
4124 #endif
4125  if (disk_read(fs->drv, fp->buf, dsc, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Load current sector */
4126 #endif
4127  fp->sect = dsc;
4128  }
4129  }
4130  }
4131  } else
4132 #endif
4133 
4134  /* Normal Seek */
4135  {
4136 #if _FS_EXFAT
4137  if (fs->fs_type != FS_EXFAT && ofs >= 0x100000000) ofs = 0xFFFFFFFF; /* Clip at 4GiB-1 if at FATxx */
4138 #endif
4139  if (ofs > fp->obj.objsize && (_FS_READONLY || !(fp->flag & FA_WRITE))) { /* In read-only mode, clip offset with the file size */
4140  ofs = fp->obj.objsize;
4141  }
4142  ifptr = fp->fptr;
4143  fp->fptr = nsect = 0;
4144  if (ofs) {
4145  bcs = (DWORD)fs->csize * SS(fs); /* Cluster size (byte) */
4146  if (ifptr > 0 &&
4147  (ofs - 1) / bcs >= (ifptr - 1) / bcs) { /* When seek to same or following cluster, */
4148  fp->fptr = (ifptr - 1) & ~(FSIZE_t)(bcs - 1); /* start from the current cluster */
4149  ofs -= fp->fptr;
4150  clst = fp->clust;
4151  } else { /* When seek to back cluster, */
4152  clst = fp->obj.sclust; /* start from the first cluster */
4153 #if !_FS_READONLY
4154  if (clst == 0) { /* If no cluster chain, create a new chain */
4155  clst = create_chain(&fp->obj, 0);
4156  if (clst == 1) ABORT(fs, FR_INT_ERR);
4157  if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
4158  fp->obj.sclust = clst;
4159  }
4160 #endif
4161  fp->clust = clst;
4162  }
4163  if (clst != 0) {
4164  while (ofs > bcs) { /* Cluster following loop */
4165  ofs -= bcs; fp->fptr += bcs;
4166 #if !_FS_READONLY
4167  if (fp->flag & FA_WRITE) { /* Check if in write mode or not */
4168  if (_FS_EXFAT && fp->fptr > fp->obj.objsize) { /* No FAT chain object needs correct objsize to generate FAT value */
4169  fp->obj.objsize = fp->fptr;
4170  fp->flag |= FA_MODIFIED;
4171  }
4172  clst = create_chain(&fp->obj, clst); /* Follow chain with forceed stretch */
4173  if (clst == 0) { /* Clip file size in case of disk full */
4174  ofs = 0; break;
4175  }
4176  } else
4177 #endif
4178  {
4179  clst = get_fat(&fp->obj, clst); /* Follow cluster chain if not in write mode */
4180  }
4181  if (clst == 0xFFFFFFFF) ABORT(fs, FR_DISK_ERR);
4182  if (clst <= 1 || clst >= fs->n_fatent) ABORT(fs, FR_INT_ERR);
4183  fp->clust = clst;
4184  }
4185  fp->fptr += ofs;
4186  if (ofs % SS(fs)) {
4187  nsect = clust2sect(fs, clst); /* Current sector */
4188  if (!nsect) ABORT(fs, FR_INT_ERR);
4189  nsect += (DWORD)(ofs / SS(fs));
4190  }
4191  }
4192  }
4193  if (!_FS_READONLY && fp->fptr > fp->obj.objsize) { /* Set file change flag if the file size is extended */
4194  fp->obj.objsize = fp->fptr;
4195  fp->flag |= FA_MODIFIED;
4196  }
4197  if (fp->fptr % SS(fs) && nsect != fp->sect) { /* Fill sector cache if needed */
4198 #if !_FS_TINY
4199 #if !_FS_READONLY
4200  if (fp->flag & FA_DIRTY) { /* Write-back dirty sector cache */
4201  if (disk_write(fs->drv, fp->buf, fp->sect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR);
4202  fp->flag &= (BYTE)~FA_DIRTY;
4203  }
4204 #endif
4205  if (disk_read(fs->drv, fp->buf, nsect, 1) != RES_OK) ABORT(fs, FR_DISK_ERR); /* Fill sector cache */
4206 #endif
4207  fp->sect = nsect;
4208  }
4209  }
4210 
4211  LEAVE_FF(fs, res);
4212 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ f_truncate()

FRESULT f_truncate ( FIL fp)
4537 {
4538  FRESULT res;
4539  FATFS *fs;
4540  DWORD ncl;
4541 
4542 
4543  res = validate(&fp->obj, &fs); /* Check validity of the file object */
4544  if (res != FR_OK || (res = (FRESULT)fp->err) != FR_OK) LEAVE_FF(fs, res);
4545  if (!(fp->flag & FA_WRITE)) LEAVE_FF(fs, FR_DENIED); /* Check access mode */
4546 
4547  if (fp->fptr < fp->obj.objsize) { /* Process when fptr is not on the eof */
4548  if (fp->fptr == 0) { /* When set file size to zero, remove entire cluster chain */
4549  res = remove_chain(&fp->obj, fp->obj.sclust, 0);
4550  fp->obj.sclust = 0;
4551  } else { /* When truncate a part of the file, remove remaining clusters */
4552  ncl = get_fat(&fp->obj, fp->clust);
4553  res = FR_OK;
4554  if (ncl == 0xFFFFFFFF) res = FR_DISK_ERR;
4555  if (ncl == 1) res = FR_INT_ERR;
4556  if (res == FR_OK && ncl < fs->n_fatent) {
4557  res = remove_chain(&fp->obj, ncl, fp->clust);
4558  }
4559  }
4560  fp->obj.objsize = fp->fptr; /* Set file size to current R/W point */
4561  fp->flag |= FA_MODIFIED;
4562 #if !_FS_TINY
4563  if (res == FR_OK && (fp->flag & FA_DIRTY)) {
4564  if (disk_write(fs->drv, fp->buf, fp->sect, 1) != RES_OK) {
4565  res = FR_DISK_ERR;
4566  } else {
4567  fp->flag &= (BYTE)~FA_DIRTY;
4568  }
4569  }
4570 #endif
4571  if (res != FR_OK) ABORT(fs, res);
4572  }
4573 
4574  LEAVE_FF(fs, res);
4575 }
Here is the call graph for this function:

◆ f_sync()

FRESULT f_sync ( FIL fp)
3723 {
3724  FRESULT res;
3725  FATFS *fs;
3726  DWORD tm;
3727  BYTE *dir;
3728 #if _FS_EXFAT
3729  DIR dj;
3730  DEF_NAMBUF
3731 #endif
3732 
3733  res = validate(&fp->obj, &fs); /* Check validity of the file object */
3734  if (res == FR_OK) {
3735  if (fp->flag & FA_MODIFIED) { /* Is there any change to the file? */
3736 #if !_FS_TINY
3737  if (fp->flag & FA_DIRTY) { /* Write-back cached data if needed */
3738  if (disk_write(fs->drv, fp->buf, fp->sect, 1) != RES_OK) LEAVE_FF(fs, FR_DISK_ERR);
3739  fp->flag &= (BYTE)~FA_DIRTY;
3740  }
3741 #endif
3742  /* Update the directory entry */
3743  tm = GET_FATTIME(); /* Modified time */
3744 #if _FS_EXFAT
3745  if (fs->fs_type == FS_EXFAT) {
3746  res = fill_first_frag(&fp->obj); /* Fill first fragment on the FAT if needed */
3747  if (res == FR_OK) {
3748  res = fill_last_frag(&fp->obj, fp->clust, 0xFFFFFFFF); /* Fill last fragment on the FAT if needed */
3749  }
3750  if (res == FR_OK) {
3751  INIT_NAMBUF(fs);
3752  res = load_obj_dir(&dj, &fp->obj); /* Load directory entry block */
3753  if (res == FR_OK) {
3754  fs->dirbuf[XDIR_Attr] |= AM_ARC; /* Set archive bit */
3755  fs->dirbuf[XDIR_GenFlags] = fp->obj.stat | 1; /* Update file allocation info */
3756  st_dword(fs->dirbuf + XDIR_FstClus, fp->obj.sclust);
3757  st_qword(fs->dirbuf + XDIR_FileSize, fp->obj.objsize);
3758  st_qword(fs->dirbuf + XDIR_ValidFileSize, fp->obj.objsize);
3759  st_dword(fs->dirbuf + XDIR_ModTime, tm); /* Update modified time */
3760  fs->dirbuf[XDIR_ModTime10] = 0;
3761  st_dword(fs->dirbuf + XDIR_AccTime, 0);
3762  res = store_xdir(&dj); /* Restore it to the directory */
3763  if (res == FR_OK) {
3764  res = sync_fs(fs);
3765  fp->flag &= (BYTE)~FA_MODIFIED;
3766  }
3767  }
3768  FREE_NAMBUF();
3769  }
3770  } else
3771 #endif
3772  {
3773  res = move_window(fs, fp->dir_sect);
3774  if (res == FR_OK) {
3775  dir = fp->dir_ptr;
3776  dir[DIR_Attr] |= AM_ARC; /* Set archive bit */
3777  st_clust(fp->obj.fs, dir, fp->obj.sclust); /* Update file allocation info */
3778  st_dword(dir + DIR_FileSize, (DWORD)fp->obj.objsize); /* Update file size */
3779  st_dword(dir + DIR_ModTime, tm); /* Update modified time */
3780  st_word(dir + DIR_LstAccDate, 0);
3781  fs->wflag = 1;
3782  res = sync_fs(fs); /* Restore it to the directory */
3783  fp->flag &= (BYTE)~FA_MODIFIED;
3784  }
3785  }
3786  }
3787  }
3788 
3789  LEAVE_FF(fs, res);
3790 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ f_opendir()

FRESULT f_opendir ( DIR dp,
const TCHAR path 
)
4225 {
4226  FRESULT res;
4227  FATFS *fs;
4228  _FDID *obj;
4229  DEF_NAMBUF
4230 
4231 
4232  if (!dp) return FR_INVALID_OBJECT;
4233 
4234  /* Get logical drive */
4235  obj = &dp->obj;
4236  res = find_volume(&path, &fs, 0);
4237  if (res == FR_OK) {
4238  obj->fs = fs;
4239  INIT_NAMBUF(fs);
4240  res = follow_path(dp, path); /* Follow the path to the directory */
4241  if (res == FR_OK) { /* Follow completed */
4242  if (!(dp->fn[NSFLAG] & NS_NONAME)) { /* It is not the origin directory itself */
4243  if (obj->attr & AM_DIR) { /* This object is a sub-directory */
4244 #if _FS_EXFAT
4245  if (fs->fs_type == FS_EXFAT) {
4246  obj->c_scl = obj->sclust; /* Get containing directory inforamation */
4247  obj->c_size = ((DWORD)obj->objsize & 0xFFFFFF00) | obj->stat;
4248  obj->c_ofs = dp->blk_ofs;
4249  obj->sclust = ld_dword(fs->dirbuf + XDIR_FstClus); /* Get object allocation info */
4250  obj->objsize = ld_qword(fs->dirbuf + XDIR_FileSize);
4251  obj->stat = fs->dirbuf[XDIR_GenFlags] & 2;
4252  } else
4253 #endif
4254  {
4255  obj->sclust = ld_clust(fs, dp->dir); /* Get object allocation info */
4256  }
4257  } else { /* This object is a file */
4258  res = FR_NO_PATH;
4259  }
4260  }
4261  if (res == FR_OK) {
4262  obj->id = fs->id;
4263  res = dir_sdi(dp, 0); /* Rewind directory */
4264 #if _FS_LOCK != 0
4265  if (res == FR_OK) {
4266  if (obj->sclust) {
4267  obj->lockid = inc_lock(dp, 0); /* Lock the sub directory */
4268  if (!obj->lockid) res = FR_TOO_MANY_OPEN_FILES;
4269  } else {
4270  obj->lockid = 0; /* Root directory need not to be locked */
4271  }
4272  }
4273 #endif
4274  }
4275  }
4276  FREE_NAMBUF();
4277  if (res == FR_NO_FILE) res = FR_NO_PATH;
4278  }
4279  if (res != FR_OK) obj->fs = 0; /* Invalidate the directory object if function faild */
4280 
4281  LEAVE_FF(fs, res);
4282 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ f_closedir()

FRESULT f_closedir ( DIR dp)
4294 {
4295  FRESULT res;
4296  FATFS *fs;
4297 
4298 
4299  res = validate(&dp->obj, &fs); /* Check validity of the file object */
4300  if (res == FR_OK) {
4301 #if _FS_LOCK != 0
4302  if (dp->obj.lockid) { /* Decrement sub-directory open counter */
4303  res = dec_lock(dp->obj.lockid);
4304  }
4305  if (res == FR_OK)
4306 #endif
4307  {
4308  dp->obj.fs = 0; /* Invalidate directory object */
4309  }
4310 #if _FS_REENTRANT
4311  unlock_fs(fs, FR_OK); /* Unlock volume */
4312 #endif
4313  }
4314  return res;
4315 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ f_readdir()

FRESULT f_readdir ( DIR dp,
FILINFO fno 
)
4328 {
4329  FRESULT res;
4330  FATFS *fs;
4331  DEF_NAMBUF
4332 
4333 
4334  res = validate(&dp->obj, &fs); /* Check validity of the directory object */
4335  if (res == FR_OK) {
4336  if (!fno) {
4337  res = dir_sdi(dp, 0); /* Rewind the directory object */
4338  } else {
4339  INIT_NAMBUF(fs);
4340  res = dir_read(dp, 0); /* Read an item */
4341  if (res == FR_NO_FILE) res = FR_OK; /* Ignore end of directory */
4342  if (res == FR_OK) { /* A valid entry is found */
4343  get_fileinfo(dp, fno); /* Get the object information */
4344  res = dir_next(dp, 0); /* Increment index for next */
4345  if (res == FR_NO_FILE) res = FR_OK; /* Ignore end of directory now */
4346  }
4347  FREE_NAMBUF();
4348  }
4349  }
4350  LEAVE_FF(fs, res);
4351 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ f_findfirst()

FRESULT f_findfirst ( DIR dp,
FILINFO fno,
const TCHAR path,
const TCHAR pattern 
)
Here is the caller graph for this function:

◆ f_findnext()

FRESULT f_findnext ( DIR dp,
FILINFO fno 
)
Here is the caller graph for this function:

◆ f_mkdir()

FRESULT f_mkdir ( const TCHAR path)
4682 {
4683  FRESULT res;
4684  DIR dj;
4685  FATFS *fs;
4686  BYTE *dir;
4687  UINT n;
4688  DWORD dsc, dcl, pcl, tm;
4689  DEF_NAMBUF
4690 
4691 
4692  /* Get logical drive */
4693  res = find_volume(&path, &fs, FA_WRITE);
4694  dj.obj.fs = fs;
4695  if (res == FR_OK) {
4696  INIT_NAMBUF(fs);
4697  res = follow_path(&dj, path); /* Follow the file path */
4698  if (res == FR_OK) res = FR_EXIST; /* Any object with same name is already existing */
4699  if (_FS_RPATH && res == FR_NO_FILE && (dj.fn[NSFLAG] & NS_DOT)) {
4700  res = FR_INVALID_NAME;
4701  }
4702  if (res == FR_NO_FILE) { /* Can create a new directory */
4703  dcl = create_chain(&dj.obj, 0); /* Allocate a cluster for the new directory table */
4704  dj.obj.objsize = (DWORD)fs->csize * SS(fs);
4705  res = FR_OK;
4706  if (dcl == 0) res = FR_DENIED; /* No space to allocate a new cluster */
4707  if (dcl == 1) res = FR_INT_ERR;
4708  if (dcl == 0xFFFFFFFF) res = FR_DISK_ERR;
4709  if (res == FR_OK) res = sync_window(fs); /* Flush FAT */
4710  tm = GET_FATTIME();
4711  if (res == FR_OK) { /* Initialize the new directory table */
4712  dsc = clust2sect(fs, dcl);
4713  dir = fs->win;
4714  mem_set(dir, 0, SS(fs));
4715  if (!_FS_EXFAT || fs->fs_type != FS_EXFAT) {
4716  mem_set(dir + DIR_Name, ' ', 11); /* Create "." entry */
4717  dir[DIR_Name] = '.';
4718  dir[DIR_Attr] = AM_DIR;
4719  st_dword(dir + DIR_ModTime, tm);
4720  st_clust(fs, dir, dcl);
4721  mem_cpy(dir + SZDIRE, dir, SZDIRE); /* Create ".." entry */
4722  dir[SZDIRE + 1] = '.'; pcl = dj.obj.sclust;
4723  if (fs->fs_type == FS_FAT32 && pcl == fs->dirbase) pcl = 0;
4724  st_clust(fs, dir + SZDIRE, pcl);
4725  }
4726  for (n = fs->csize; n; n--) { /* Write dot entries and clear following sectors */
4727  fs->winsect = dsc++;
4728  fs->wflag = 1;
4729  res = sync_window(fs);
4730  if (res != FR_OK) break;
4731  mem_set(dir, 0, SS(fs));
4732  }
4733  }
4734  if (res == FR_OK) {
4735  res = dir_register(&dj); /* Register the object to the directoy */
4736  }
4737  if (res == FR_OK) {
4738 #if _FS_EXFAT
4739  if (fs->fs_type == FS_EXFAT) { /* Initialize directory entry block */
4740  st_dword(fs->dirbuf + XDIR_ModTime, tm); /* Created time */
4741  st_dword(fs->dirbuf + XDIR_FstClus, dcl); /* Table start cluster */
4742  st_dword(fs->dirbuf + XDIR_FileSize, (DWORD)dj.obj.objsize); /* File size needs to be valid */
4743  st_dword(fs->dirbuf + XDIR_ValidFileSize, (DWORD)dj.obj.objsize);
4744  fs->dirbuf[XDIR_GenFlags] = 3; /* Initialize the object flag (contiguous) */
4745  fs->dirbuf[XDIR_Attr] = AM_DIR; /* Attribute */
4746  res = store_xdir(&dj);
4747  } else
4748 #endif
4749  {
4750  dir = dj.dir;
4751  st_dword(dir + DIR_ModTime, tm); /* Created time */
4752  st_clust(fs, dir, dcl); /* Table start cluster */
4753  dir[DIR_Attr] = AM_DIR; /* Attribute */
4754  fs->wflag = 1;
4755  }
4756  if (res == FR_OK) {
4757  res = sync_fs(fs);
4758  }
4759  } else {
4760  remove_chain(&dj.obj, dcl, 0); /* Could not register, remove cluster chain */
4761  }
4762  }
4763  FREE_NAMBUF();
4764  }
4765 
4766  LEAVE_FF(fs, res);
4767 }
Here is the call graph for this function:

◆ f_unlink()

FRESULT f_unlink ( const TCHAR path)
4587 {
4588  FRESULT res;
4589  DIR dj, sdj;
4590  DWORD dclst = 0;
4591  FATFS *fs;
4592 #if _FS_EXFAT
4593  _FDID obj;
4594 #endif
4595  DEF_NAMBUF
4596 
4597 
4598  /* Get logical drive */
4599  res = find_volume(&path, &fs, FA_WRITE);
4600  dj.obj.fs = fs;
4601  if (res == FR_OK) {
4602  INIT_NAMBUF(fs);
4603  res = follow_path(&dj, path); /* Follow the file path */
4604  if (_FS_RPATH && res == FR_OK && (dj.fn[NSFLAG] & NS_DOT)) {
4605  res = FR_INVALID_NAME; /* Cannot remove dot entry */
4606  }
4607 #if _FS_LOCK != 0
4608  if (res == FR_OK) res = chk_lock(&dj, 2); /* Check if it is an open object */
4609 #endif
4610  if (res == FR_OK) { /* The object is accessible */
4611  if (dj.fn[NSFLAG] & NS_NONAME) {
4612  res = FR_INVALID_NAME; /* Cannot remove the origin directory */
4613  } else {
4614  if (dj.obj.attr & AM_RDO) {
4615  res = FR_DENIED; /* Cannot remove R/O object */
4616  }
4617  }
4618  if (res == FR_OK) {
4619 #if _FS_EXFAT
4620  obj.fs = fs;
4621  if (fs->fs_type == FS_EXFAT) {
4622  obj.sclust = dclst = ld_dword(fs->dirbuf + XDIR_FstClus);
4623  obj.objsize = ld_qword(fs->dirbuf + XDIR_FileSize);
4624  obj.stat = fs->dirbuf[XDIR_GenFlags] & 2;
4625  } else
4626 #endif
4627  {
4628  dclst = ld_clust(fs, dj.dir);
4629  }
4630  if (dj.obj.attr & AM_DIR) { /* Is it a sub-directory? */
4631 #if _FS_RPATH != 0
4632  if (dclst == fs->cdir) { /* Is it the current directory? */
4633  res = FR_DENIED;
4634  } else
4635 #endif
4636  {
4637  sdj.obj.fs = fs; /* Open the sub-directory */
4638  sdj.obj.sclust = dclst;
4639 #if _FS_EXFAT
4640  if (fs->fs_type == FS_EXFAT) {
4641  sdj.obj.objsize = obj.objsize;
4642  sdj.obj.stat = obj.stat;
4643  }
4644 #endif
4645  res = dir_sdi(&sdj, 0);
4646  if (res == FR_OK) {
4647  res = dir_read(&sdj, 0); /* Read an item */
4648  if (res == FR_OK) res = FR_DENIED; /* Not empty? */
4649  if (res == FR_NO_FILE) res = FR_OK; /* Empty? */
4650  }
4651  }
4652  }
4653  }
4654  if (res == FR_OK) {
4655  res = dir_remove(&dj); /* Remove the directory entry */
4656  if (res == FR_OK && dclst) { /* Remove the cluster chain if exist */
4657 #if _FS_EXFAT
4658  res = remove_chain(&obj, dclst, 0);
4659 #else
4660  res = remove_chain(&dj.obj, dclst, 0);
4661 #endif
4662  }
4663  if (res == FR_OK) res = sync_fs(fs);
4664  }
4665  }
4666  FREE_NAMBUF();
4667  }
4668 
4669  LEAVE_FF(fs, res);
4670 }
Here is the call graph for this function:

◆ f_rename()

FRESULT f_rename ( const TCHAR path_old,
const TCHAR path_new 
)
4780 {
4781  FRESULT res;
4782  DIR djo, djn;
4783  FATFS *fs;
4784  BYTE buf[_FS_EXFAT ? SZDIRE * 2 : 24], *dir;
4785  DWORD dw;
4786  DEF_NAMBUF
4787 
4788 
4789  get_ldnumber(&path_new); /* Snip drive number of new name off */
4790  res = find_volume(&path_old, &fs, FA_WRITE); /* Get logical drive of the old object */
4791  if (res == FR_OK) {
4792  djo.obj.fs = fs;
4793  INIT_NAMBUF(fs);
4794  res = follow_path(&djo, path_old); /* Check old object */
4795  if (res == FR_OK && (djo.fn[NSFLAG] & (NS_DOT | NS_NONAME))) res = FR_INVALID_NAME; /* Check validity of name */
4796 #if _FS_LOCK != 0
4797  if (res == FR_OK) {
4798  res = chk_lock(&djo, 2);
4799  }
4800 #endif
4801  if (res == FR_OK) { /* Object to be renamed is found */
4802 #if _FS_EXFAT
4803  if (fs->fs_type == FS_EXFAT) { /* At exFAT */
4804  BYTE nf, nn;
4805  WORD nh;
4806 
4807  mem_cpy(buf, fs->dirbuf, SZDIRE * 2); /* Save 85+C0 entry of old object */
4808  mem_cpy(&djn, &djo, sizeof djo);
4809  res = follow_path(&djn, path_new); /* Make sure if new object name is not in use */
4810  if (res == FR_OK) { /* Is new name already in use by any other object? */
4811  res = (djn.obj.sclust == djo.obj.sclust && djn.dptr == djo.dptr) ? FR_NO_FILE : FR_EXIST;
4812  }
4813  if (res == FR_NO_FILE) { /* It is a valid path and no name collision */
4814  res = dir_register(&djn); /* Register the new entry */
4815  if (res == FR_OK) {
4816  nf = fs->dirbuf[XDIR_NumSec]; nn = fs->dirbuf[XDIR_NumName];
4817  nh = ld_word(fs->dirbuf + XDIR_NameHash);
4818  mem_cpy(fs->dirbuf, buf, SZDIRE * 2);
4819  fs->dirbuf[XDIR_NumSec] = nf; fs->dirbuf[XDIR_NumName] = nn;
4820  st_word(fs->dirbuf + XDIR_NameHash, nh);
4821 /* Start of critical section where an interruption can cause a cross-link */
4822  res = store_xdir(&djn);
4823  }
4824  }
4825  } else
4826 #endif
4827  { /* At FAT12/FAT16/FAT32 */
4828  mem_cpy(buf, djo.dir + DIR_Attr, 21); /* Save information about the object except name */
4829  mem_cpy(&djn, &djo, sizeof (DIR)); /* Duplicate the directory object */
4830  res = follow_path(&djn, path_new); /* Make sure if new object name is not in use */
4831  if (res == FR_OK) { /* Is new name already in use by any other object? */
4832  res = (djn.obj.sclust == djo.obj.sclust && djn.dptr == djo.dptr) ? FR_NO_FILE : FR_EXIST;
4833  }
4834  if (res == FR_NO_FILE) { /* It is a valid path and no name collision */
4835  res = dir_register(&djn); /* Register the new entry */
4836  if (res == FR_OK) {
4837  dir = djn.dir; /* Copy information about object except name */
4838  mem_cpy(dir + 13, buf + 2, 19);
4839  dir[DIR_Attr] = buf[0] | AM_ARC;
4840  fs->wflag = 1;
4841  if ((dir[DIR_Attr] & AM_DIR) && djo.obj.sclust != djn.obj.sclust) { /* Update .. entry in the sub-directory if needed */
4842  dw = clust2sect(fs, ld_clust(fs, dir));
4843  if (!dw) {
4844  res = FR_INT_ERR;
4845  } else {
4846 /* Start of critical section where an interruption can cause a cross-link */
4847  res = move_window(fs, dw);
4848  dir = fs->win + SZDIRE * 1; /* Ptr to .. entry */
4849  if (res == FR_OK && dir[1] == '.') {
4850  st_clust(fs, dir, djn.obj.sclust);
4851  fs->wflag = 1;
4852  }
4853  }
4854  }
4855  }
4856  }
4857  }
4858  if (res == FR_OK) {
4859  res = dir_remove(&djo); /* Remove old entry */
4860  if (res == FR_OK) {
4861  res = sync_fs(fs);
4862  }
4863  }
4864 /* End of the critical section */
4865  }
4866  FREE_NAMBUF();
4867  }
4868 
4869  LEAVE_FF(fs, res);
4870 }
Here is the call graph for this function:

◆ f_stat()

FRESULT f_stat ( const TCHAR path,
FILINFO fno 
)
4416 {
4417  FRESULT res;
4418  DIR dj;
4419  DEF_NAMBUF
4420 
4421 
4422  /* Get logical drive */
4423  res = find_volume(&path, &dj.obj.fs, 0);
4424  if (res == FR_OK) {
4425  INIT_NAMBUF(dj.obj.fs);
4426  res = follow_path(&dj, path); /* Follow the file path */
4427  if (res == FR_OK) { /* Follow completed */
4428  if (dj.fn[NSFLAG] & NS_NONAME) { /* It is origin directory */
4429  res = FR_INVALID_NAME;
4430  } else { /* Found an object */
4431  if (fno) get_fileinfo(&dj, fno);
4432  }
4433  }
4434  FREE_NAMBUF();
4435  }
4436 
4437  LEAVE_FF(dj.obj.fs, res);
4438 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ f_chmod()

FRESULT f_chmod ( const TCHAR path,
BYTE  attr,
BYTE  mask 
)

◆ f_utime()

FRESULT f_utime ( const TCHAR path,
const FILINFO fno 
)

◆ f_chdir()

FRESULT f_chdir ( const TCHAR path)

◆ f_chdrive()

FRESULT f_chdrive ( const TCHAR path)

◆ f_getcwd()

FRESULT f_getcwd ( TCHAR buff,
UINT  len 
)

◆ f_getdirpath()

FRESULT f_getdirpath ( DIR pd,
TCHAR buff,
UINT  len 
)
Here is the caller graph for this function:

◆ f_getfree()

FRESULT f_getfree ( const TCHAR path,
DWORD nclst,
FATFS **  fatfs 
)
4452 {
4453  FRESULT res;
4454  FATFS *fs;
4455  DWORD nfree, clst, sect, stat;
4456  UINT i;
4457  BYTE *p;
4458  _FDID obj;
4459 
4460 
4461  /* Get logical drive */
4462  res = find_volume(&path, &fs, 0);
4463  if (res == FR_OK) {
4464  *fatfs = fs; /* Return ptr to the fs object */
4465  /* If free_clst is valid, return it without full cluster scan */
4466  if (fs->free_clst <= fs->n_fatent - 2) {
4467  *nclst = fs->free_clst;
4468  } else {
4469  /* Get number of free clusters */
4470  nfree = 0;
4471  if (fs->fs_type == FS_FAT12) { /* FAT12: Sector unalighed FAT entries */
4472  clst = 2; obj.fs = fs;
4473  do {
4474  stat = get_fat(&obj, clst);
4475  if (stat == 0xFFFFFFFF) { res = FR_DISK_ERR; break; }
4476  if (stat == 1) { res = FR_INT_ERR; break; }
4477  if (stat == 0) nfree++;
4478  } while (++clst < fs->n_fatent);
4479  } else {
4480 #if _FS_EXFAT
4481  if (fs->fs_type == FS_EXFAT) { /* exFAT: Scan bitmap table */
4482  BYTE bm;
4483  UINT b;
4484 
4485  clst = fs->n_fatent - 2;
4486  sect = fs->database;
4487  i = 0;
4488  do {
4489  if (i == 0 && (res = move_window(fs, sect++)) != FR_OK) break;
4490  for (b = 8, bm = fs->win[i]; b && clst; b--, clst--) {
4491  if (!(bm & 1)) nfree++;
4492  bm >>= 1;
4493  }
4494  i = (i + 1) % SS(fs);
4495  } while (clst);
4496  } else
4497 #endif
4498  { /* FAT16/32: Sector alighed FAT entries */
4499  clst = fs->n_fatent; sect = fs->fatbase;
4500  i = 0; p = 0;
4501  do {
4502  if (i == 0) {
4503  res = move_window(fs, sect++);
4504  if (res != FR_OK) break;
4505  p = fs->win;
4506  i = SS(fs);
4507  }
4508  if (fs->fs_type == FS_FAT16) {
4509  if (ld_word(p) == 0) nfree++;
4510  p += 2; i -= 2;
4511  } else {
4512  if ((ld_dword(p) & 0x0FFFFFFF) == 0) nfree++;
4513  p += 4; i -= 4;
4514  }
4515  } while (--clst);
4516  }
4517  }
4518  *nclst = nfree; /* Return the free clusters */
4519  fs->free_clst = nfree; /* Now free_clst is valid */
4520  fs->fsi_flag |= 1; /* FSInfo is to be updated */
4521  }
4522  }
4523 
4524  LEAVE_FF(fs, res);
4525 }
Here is the call graph for this function:

◆ f_getlabel()

FRESULT f_getlabel ( const TCHAR path,
TCHAR label,
DWORD vsn 
)

◆ f_setlabel()

FRESULT f_setlabel ( const TCHAR label)

◆ f_forward()

FRESULT f_forward ( FIL fp,
UINT(*)(const BYTE *, UINT func,
UINT  btf,
UINT bf 
)

◆ f_expand()

FRESULT f_expand ( FIL fp,
FSIZE_t  szf,
BYTE  opt 
)

◆ f_mount()

FRESULT f_mount ( FATFS fs,
const TCHAR path,
BYTE  opt 
)
3253 {
3254  FATFS *cfs;
3255  int vol;
3256  FRESULT res;
3257  const TCHAR *rp = path;
3258 
3259 
3260  /* Get logical drive number */
3261  vol = get_ldnumber(&rp);
3262  if (vol < 0) return FR_INVALID_DRIVE;
3263  cfs = FatFs[vol]; /* Pointer to fs object */
3264 
3265  if (cfs) {
3266 #if _FS_LOCK != 0
3267  clear_lock(cfs);
3268 #endif
3269 #if _FS_REENTRANT /* Discard sync object of the current volume */
3270  if (!ff_del_syncobj(cfs->sobj)) return FR_INT_ERR;
3271 #endif
3272  cfs->fs_type = 0; /* Clear old fs object */
3273  }
3274 
3275  if (fs) {
3276  fs->fs_type = 0; /* Clear new fs object */
3277 #if _FS_REENTRANT /* Create sync object for the new volume */
3278  if (!ff_cre_syncobj((BYTE)vol, &fs->sobj)) return FR_INT_ERR;
3279 #endif
3280  }
3281  FatFs[vol] = fs; /* Register new fs object */
3282 
3283  if (!fs || opt != 1) return FR_OK; /* Do not mount now, it will be mounted later */
3284 
3285  res = find_volume(&path, &fs, 0); /* Force mounted the volume */
3286  LEAVE_FF(fs, res);
3287 }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ f_mkfs()

FRESULT f_mkfs ( const TCHAR path,
BYTE  opt,
DWORD  au,
void work,
UINT  len 
)

◆ f_fdisk()

FRESULT f_fdisk ( BYTE  pdrv,
const DWORD szt,
void work 
)

◆ f_putc()

int f_putc ( TCHAR  c,
FIL fp 
)

◆ f_puts()

int f_puts ( const TCHAR str,
FIL cp 
)

◆ f_printf()

int f_printf ( FIL fp,
const TCHAR str,
  ... 
)

◆ f_gets()

TCHAR* f_gets ( TCHAR buff,
int  len,
FIL fp 
)

◆ get_fattime()

DWORD get_fattime ( void  )

Gets Time from RTC.

Parameters
None
Return values
Timein DWORD
176 {
177  return 0;
178 }
dir_read
static FRESULT dir_read(DIR *dp, int vol)
Definition: ff.c:2131
FR_NOT_ENOUGH_CORE
Definition: ff.h:232
FA_OPEN_ALWAYS
#define FA_OPEN_ALWAYS
Definition: ff.h:331
XDIR_FstClus
#define XDIR_FstClus
Definition: ff.c:427
TCHAR
char TCHAR
Definition: ff.h:62
XDIR_FileSize
#define XDIR_FileSize
Definition: ff.c:428
dir_next
static FRESULT dir_next(DIR *dp, int stretch)
Definition: ff.c:1519
XDIR_ValidFileSize
#define XDIR_ValidFileSize
Definition: ff.c:426
FR_DISK_ERR
Definition: ff.h:216
FR_INVALID_OBJECT
Definition: ff.h:224
DIR_CrtTime
#define DIR_CrtTime
Definition: ff.c:397
FR_EXIST
Definition: ff.h:223
FATFS::fatbase
DWORD fatbase
Definition: ff.h:121
FATFS::last_clst
DWORD last_clst
Definition: ff.h:107
dir_sdi
static FRESULT dir_sdi(DIR *dp, DWORD ofs)
Definition: ff.c:1470
_FDID::stat
BYTE stat
Definition: ff.h:136
FR_NO_FILE
Definition: ff.h:219
FA_WRITE
#define FA_WRITE
Definition: ff.h:327
st_dword
static void st_dword(BYTE *ptr, DWORD val)
Definition: ff.c:661
DIR_FileSize
#define DIR_FileSize
Definition: ff.c:402
XDIR_AccTime
#define XDIR_AccTime
Definition: ff.c:417
FATFS::csize
WORD csize
Definition: ff.h:93
FIL::fptr
FSIZE_t fptr
Definition: ff.h:159
FATFS::winsect
DWORD winsect
Definition: ff.h:124
CREATE_LINKMAP
#define CREATE_LINKMAP
Definition: ff.h:335
INIT_NAMBUF
#define INIT_NAMBUF(fs)
Definition: ff.c:546
FR_NO_PATH
Definition: ff.h:220
FA_OPEN_APPEND
#define FA_OPEN_APPEND
Definition: ff.h:332
FIL::clust
DWORD clust
Definition: ff.h:160
dir_remove
static FRESULT dir_remove(DIR *dp)
Definition: ff.c:2396
validate
static FRESULT validate(_FDID *obj, FATFS **fs)
Definition: ff.c:3215
FA_CREATE_ALWAYS
#define FA_CREATE_ALWAYS
Definition: ff.h:330
FATFS::n_fatent
DWORD n_fatent
Definition: ff.h:118
WORD
unsigned short WORD
Definition: onboard_sd.h:14
FIL::obj
_FDID obj
Definition: ff.h:156
disk_read
DRESULT disk_read(BYTE pdrv, BYTE *buff, DWORD sector, UINT count)
Reads Sector(s)
Definition: diskio.c:113
i
uint8_t i
Definition: screen_test_graph.c:72
get_fileinfo
static void get_fileinfo(DIR *dp, FILINFO *fno)
Definition: ff.c:2444
FS_EXFAT
#define FS_EXFAT
Definition: ff.h:348
_FDID::sclust
DWORD sclust
Definition: ff.h:137
FSIZE_t
DWORD FSIZE_t
Definition: ff.h:78
ld_clust
static DWORD ld_clust(FATFS *fs, const BYTE *dir)
Definition: ff.c:1632
NS_NONAME
#define NS_NONAME
Definition: ff.c:321
FR_WRITE_PROTECTED
Definition: ff.h:225
clust2sect
static DWORD clust2sect(FATFS *fs, DWORD clst)
Definition: ff.c:983
remove_chain
static FRESULT remove_chain(_FDID *obj, DWORD clst, DWORD pclst)
Definition: ff.c:1271
FS_FAT16
#define FS_FAT16
Definition: ff.h:346
DIR_ModTime
#define DIR_ModTime
Definition: ff.c:400
DIR::fn
BYTE fn[12]
Definition: ff.h:184
dir_register
static FRESULT dir_register(DIR *dp)
Definition: ff.c:2292
DIR::dptr
DWORD dptr
Definition: ff.h:180
FIL::flag
BYTE flag
Definition: ff.h:157
sync_window
static FRESULT sync_window(FATFS *fs)
Definition: ff.c:883
NSFLAG
#define NSFLAG
Definition: ff.c:313
DIR_Name
#define DIR_Name
Definition: ff.c:393
ld_word
static WORD ld_word(const BYTE *ptr)
Definition: ff.c:613
DIR::dir
BYTE * dir
Definition: ff.h:183
BYTE
#define BYTE
Definition: MarlinSerial.h:142
st_clust
static void st_clust(FATFS *fs, BYTE *dir, DWORD cl)
Definition: ff.c:1650
FA_MODIFIED
#define FA_MODIFIED
Definition: ff.c:308
_FS_RPATH
#define _FS_RPATH
Definition: ffconf.h:182
FR_LOCKED
Definition: ff.h:231
mem_cpy
static void mem_cpy(void *dst, const void *src, UINT cnt)
Definition: ff.c:693
XDIR_CrtTime
#define XDIR_CrtTime
Definition: ff.c:415
ld_dword
static DWORD ld_dword(const BYTE *ptr)
Definition: ff.c:623
FR_NOT_ENABLED
Definition: ff.h:227
FATFS::fsi_flag
BYTE fsi_flag
Definition: ff.h:90
XDIR_NameHash
#define XDIR_NameHash
Definition: ff.c:425
_FDID::objsize
FSIZE_t objsize
Definition: ff.h:138
FATFS
Definition: ff.h:85
XDIR_ModTime
#define XDIR_ModTime
Definition: ff.c:416
FA_READ
#define FA_READ
Definition: ff.h:326
FS_FAT32
#define FS_FAT32
Definition: ff.h:347
follow_path
static FRESULT follow_path(DIR *dp, const TCHAR *path)
Definition: ff.c:2812
XDIR_Attr
#define XDIR_Attr
Definition: ff.c:414
st_word
static void st_word(BYTE *ptr, WORD val)
Definition: ff.c:654
find_volume
static FRESULT find_volume(const TCHAR **path, FATFS **rfs, BYTE mode)
Definition: ff.c:2992
GET_FATTIME
#define GET_FATTIME()
Definition: ff.c:499
create_chain
static DWORD create_chain(_FDID *obj, DWORD clst)
Definition: ff.c:1351
mem_set
static void mem_set(void *dst, int val, UINT cnt)
Definition: ff.c:706
FIL::dir_ptr
BYTE * dir_ptr
Definition: ff.h:164
FA_SEEKEND
#define FA_SEEKEND
Definition: ff.c:307
_FDID::id
WORD id
Definition: ff.h:134
NS_DOT
#define NS_DOT
Definition: ff.c:319
RES_OK
Definition: onboard_sd.h:23
FR_DENIED
Definition: ff.h:222
DIR_Attr
#define DIR_Attr
Definition: ff.c:394
FR_MKFS_ABORTED
Definition: ff.h:229
FR_NOT_READY
Definition: ff.h:218
if
if(size<=((png_alloc_size_t) -1) - ob)
Definition: pngwrite.c:2176
FATFS::id
WORD id
Definition: ff.h:91
FIL::err
BYTE err
Definition: ff.h:158
FATFS::fs_type
BYTE fs_type
Definition: ff.h:86
disk_write
DRESULT disk_write(BYTE pdrv, const BYTE *buff, DWORD sector, UINT count)
Writes Sector(s)
Definition: diskio.c:135
FATFS::wflag
BYTE wflag
Definition: ff.h:89
_FDID
Definition: ff.h:132
FR_NO_FILESYSTEM
Definition: ff.h:228
FATFS::win
BYTE win[_MAX_SS]
Definition: ff.h:125
FIL::dir_sect
DWORD dir_sect
Definition: ff.h:163
XDIR_GenFlags
#define XDIR_GenFlags
Definition: ff.c:423
XDIR_NumName
#define XDIR_NumName
Definition: ff.c:424
LEAVE_FF
#define LEAVE_FF(fs, res)
Definition: ff.c:467
SS
#define SS(fs)
Definition: ff.c:486
FATFS::free_clst
DWORD free_clst
Definition: ff.h:108
DWORD
unsigned long DWORD
Definition: onboard_sd.h:15
get_fat
static DWORD get_fat(_FDID *obj, DWORD clst)
Definition: ff.c:1001
FR_INT_ERR
Definition: ff.h:217
FRESULT
FRESULT
Definition: ff.h:214
AM_DIR
#define AM_DIR
Definition: ff.h:354
_FS_READONLY
#define _FS_READONLY
Definition: ffconf.h:69
rbuff
uint8_t rbuff[10]
Definition: HardwareSerial.cpp:19
XDIR_NumSec
#define XDIR_NumSec
Definition: ff.c:412
_FS_EXFAT
#define _FS_EXFAT
Definition: ffconf.h:249
FR_OK
Definition: ff.h:215
FIL::buf
BYTE buf[_MAX_SS]
Definition: ff.h:170
FREE_NAMBUF
#define FREE_NAMBUF()
Definition: ff.c:547
FS_FAT12
#define FS_FAT12
Definition: ff.h:345
ABORT
#define ABORT(fs, res)
Definition: ff.c:455
get_ldnumber
static int get_ldnumber(const TCHAR **path)
Definition: ff.c:2903
FIL::sect
DWORD sect
Definition: ff.h:161
DIR
Definition: ff.h:178
FR_INVALID_PARAMETER
Definition: ff.h:234
sync_fs
static FRESULT sync_fs(FATFS *fs)
Definition: ff.c:944
FR_TOO_MANY_OPEN_FILES
Definition: ff.h:233
XDIR_CrtTime10
#define XDIR_CrtTime10
Definition: ff.c:418
BYTE
unsigned char BYTE
Definition: onboard_sd.h:13
FATFS::dirbase
DWORD dirbase
Definition: ff.h:122
_FDID::fs
FATFS * fs
Definition: ff.h:133
FATFS::drv
BYTE drv
Definition: ff.h:87
XDIR_ModTime10
#define XDIR_ModTime10
Definition: ff.c:419
FR_INVALID_NAME
Definition: ff.h:221
DEF_NAMBUF
#define DEF_NAMBUF
Definition: ff.c:545
FA_DIRTY
#define FA_DIRTY
Definition: ff.c:309
SZDIRE
#define SZDIRE
Definition: ff.c:430
mode
png_structrp int mode
Definition: png.h:1139
createSpeedLookupTable.b
list b
Definition: createSpeedLookupTable.py:30
AM_RDO
#define AM_RDO
Definition: ff.h:351
UINT
unsigned int UINT
Definition: onboard_sd.h:16
FR_TIMEOUT
Definition: ff.h:230
AM_ARC
#define AM_ARC
Definition: ff.h:355
FR_INVALID_DRIVE
Definition: ff.h:226
f_sync
FRESULT f_sync(FIL *fp)
Definition: ff.c:3720
FATFS::database
DWORD database
Definition: ff.h:123
DIR::obj
_FDID obj
Definition: ff.h:179
move_window
static FRESULT move_window(FATFS *fs, DWORD sector)
Definition: ff.c:912
FA_CREATE_NEW
#define FA_CREATE_NEW
Definition: ff.h:329
FatFs
static FATFS * FatFs[_VOLUMES]
Definition: ff.c:533
_FDID::attr
BYTE attr
Definition: ff.h:135
_MAX_SS
#define _MAX_SS
Definition: ffconf.h:215
DIR_LstAccDate
#define DIR_LstAccDate
Definition: ff.c:398