⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ff.c

📁 最新的LPC214X FATFS驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
    fs->fsi_sector = bootsect + LD_U16(&fs->win[BPB_FSInfo]);    if (diskRead(0, fs->win, fs->fsi_sector, 1) == DRESULT_OK &&        LD_U16(&fs->win[BS_55AA]) == 0xAA55 &&        LD_U32(&fs->win[FSI_LeadSig]) == 0x41615252 &&        LD_U32(&fs->win[FSI_StrucSig]) == 0x61417272) {      fs->last_clust = LD_U32(&fs->win[FSI_Nxt_Free]);      fs->free_clust = LD_U32(&fs->win[FSI_Free_Count]);    }  }#endif#endif  fs->id = ++fsid;                  /* File system mount ID */  return FR_OK;}/*-----------------------------------------------------------------------*//* Check if the file/dir object is valid or not                          *//*-----------------------------------------------------------------------*/staticFRESULT validate (    /* FR_OK(0): The object is valid, !=0: Not valid */    const FATFS *fs,  /* Pointer to the file system object */    U16 id        /* id member of the target object to be checked */    ){  if (!fs || fs->id != id)    return FR_INVALID_OBJECT;  if (diskStatus(fs->drive) & DSTATUS_NOINIT)    return FR_NOT_READY;  return FR_OK;}/*--------------------------------------------------------------------------  Public Functions  --------------------------------------------------------------------------*/const char *f_ferrorlookup (FRESULT f){  unsigned int i;  typedef struct errorStrings_s  {    FRESULT fresult;    const char *string;  }  errorStrings_t;  static const errorStrings_t errorStrings [] =  {    { FR_OK,              "OK"              },    { FR_NOT_READY,       "NOT_READY"       },    { FR_NO_FILE,         "NO_FILE"         },    { FR_NO_PATH,         "NO_PATH"         },    { FR_INVALID_NAME,    "INVALID_NAME"    },    { FR_INVALID_DRIVE,   "INVALID_DRIVE"   },    { FR_DENIED,          "DENIED"          },    { FR_EXIST,           "EXIST"           },    { FR_RW_ERROR,        "RW_ERROR"        },    { FR_WRITE_PROTECTED, "WRITE_PROTECTED" },    { FR_NOT_ENABLED,     "NOT_ENABLED"     },    { FR_NO_FILESYSTEM,   "NO_FILESYSTEM"   },    { FR_INVALID_OBJECT,  "INVALID_OBJECT"  },    { FR_MKFS_ABORTED,    "MKFS_ABORTED"    },  };  for (i = 0; i < arrsizeof (errorStrings); i++)    if (errorStrings [i].fresult == f)      return errorStrings [f].string;  return "(no err text)";}void f_printerror (FRESULT f){  printf ("rrc=%u %s\n", f, f_ferrorlookup (f));}/*-----------------------------------------------------------------------*//* Mount/Unmount a Locical Drive                                         *//*-----------------------------------------------------------------------*/FRESULT f_mount (U8 drv, FATFS *fs){  FATFS *fsobj;  if (drv >= _DRIVES)     return FR_INVALID_DRIVE;  fsobj = FatFs [drv];  FatFs [drv] = fs;  if (fsobj)     memset (fsobj, 0, sizeof (FATFS));  if (fs)     memset (fs, 0, sizeof (FATFS));  return FR_OK;}/*-----------------------------------------------------------------------*//* Open or Create a File                                                 *//*-----------------------------------------------------------------------*/FRESULT f_open (    FIL *fp,      /* Pointer to the blank file object */    const char *path, /* Pointer to the file name */    U8 mode     /* Access mode and file open mode flags */    ){  FRESULT res;  U8 *dir;  DIR dirobj;  char fn[8+3+1];  FATFS *fs;  fp->fs = NULL;#if !_FS_READONLY  mode &= (FA_READ|FA_WRITE|FA_CREATE_ALWAYS|FA_OPEN_ALWAYS|FA_CREATE_NEW);  res = auto_mount(&path, &fs, (U8)(mode & (FA_WRITE|FA_CREATE_ALWAYS|FA_OPEN_ALWAYS|FA_CREATE_NEW)));#else  mode &= FA_READ;  res = auto_mount(&path, &fs, 0);#endif  if (res != FR_OK) return res;  dirobj.fs = fs;  /* Trace the file path */  res = trace_path(&dirobj, fn, path, &dir);#if !_FS_READONLY  /* Create or Open a file */  if (mode & (FA_CREATE_ALWAYS|FA_OPEN_ALWAYS|FA_CREATE_NEW)) {    U32 ps, rs;    if (res != FR_OK) {   /* No file, create new */      if (res != FR_NO_FILE) return res;      res = reserve_direntry(&dirobj, &dir);      if (res != FR_OK) return res;      memset(dir, 0, 32);           /* Initialize the new entry with open name */      memcpy(&dir[DIR_Name], fn, 8+3);      dir[DIR_NTres] = fn[11];      mode |= FA_CREATE_ALWAYS;    }    else {          /* Any object is already existing */      if (mode & FA_CREATE_NEW)     /* Cannot create new */        return FR_EXIST;      if (dir == NULL || (dir[DIR_Attr] & (AM_RDO|AM_DIR))) /* Cannot overwrite it (R/O or DIR) */        return FR_DENIED;      if (mode & FA_CREATE_ALWAYS) {    /* Resize it to zero if needed */        rs = ((U32)LD_U16(&dir[DIR_FstClusHI]) << 16) | LD_U16(&dir[DIR_FstClusLO]);  /* Get start cluster */        ST_U16(&dir[DIR_FstClusHI], 0); /* cluster = 0 */        ST_U16(&dir[DIR_FstClusLO], 0);        ST_U32(&dir[DIR_FileSize], 0);  /* size = 0 */        fs->winflag = 1;        ps = fs->winsect;       /* Remove the cluster chain */        if (!remove_chain(fs, rs) || !move_window(fs, ps))          return FR_RW_ERROR;        fs->last_clust = rs - 1;    /* Reuse the cluster hole */      }    }    if (mode & FA_CREATE_ALWAYS) {      dir[DIR_Attr] = AM_ARC;       /* New attribute */      ps = get_fattime();      ST_U32(&dir[DIR_WrtTime], ps);  /* Updated time */      ST_U32(&dir[DIR_CrtTime], ps);  /* Created time */      fs->winflag = 1;    }  }  /* Open an existing file */  else {#endif /* !_FS_READONLY */    if (res != FR_OK) return res;   /* Trace failed */    if (dir == NULL || (dir[DIR_Attr] & AM_DIR))  /* It is a directory */      return FR_NO_FILE;#if !_FS_READONLY    if ((mode & FA_WRITE) && (dir[DIR_Attr] & AM_RDO)) /* R/O violation */      return FR_DENIED;  }  fp->dir_sect = fs->winsect;     /* Pointer to the directory entry */  fp->dir_ptr = dir;#endif  fp->flag = mode;          /* File access mode */  fp->org_clust =           /* File start cluster */    ((U32)LD_U16(&dir[DIR_FstClusHI]) << 16) | LD_U16(&dir[DIR_FstClusLO]);  fp->fsize = LD_U32(&dir[DIR_FileSize]); /* File size */  fp->fptr = 0;           /* File ptr */  fp->sect_clust = 1;         /* Sector counter */  fp->fs = fs; fp->id = fs->id;   /* Owner file system object of the file */  return FR_OK;}/*-----------------------------------------------------------------------*//* Read File                                                             *//*-----------------------------------------------------------------------*/FRESULT f_read (    FIL *fp,    /* Pointer to the file object */    void *buff,   /* Pointer to data buffer */    U16 btr,    /* Number of bytes to read */    U16 *br   /* Pointer to number of bytes read */    ){  U32 clust, sect, remain;  U16 rcnt;  U8 cc, *rbuff = buff;  FRESULT res;  FATFS *fs = fp->fs;  *br = 0;  res = validate(fs, fp->id);           /* Check validity of the object */  if (res) return res;  if (fp->flag & FA__ERROR) return FR_RW_ERROR; /* Check error flag */  if (!(fp->flag & FA_READ)) return FR_DENIED;  /* Check access mode */  remain = fp->fsize - fp->fptr;  if (btr > remain) btr = (U16)remain;      /* Truncate read count by number of bytes left */  for ( ;  btr;                 /* Repeat until all data transferred */      rbuff += rcnt, fp->fptr += rcnt, *br += rcnt, btr -= rcnt) {    if ((fp->fptr & (S_SIZ - 1)) == 0) {    /* On the sector boundary */      if (--fp->sect_clust) {         /* Decrement left sector counter */        sect = fp->curr_sect + 1;     /* Get current sector */      } else {                /* On the cluster boundary, get next cluster */        clust = (fp->fptr == 0) ?          fp->org_clust : get_cluster(fs, fp->curr_clust);        if (clust < 2 || clust >= fs->max_clust)          goto fr_error;        fp->curr_clust = clust;       /* Current cluster */        sect = clust2sect(fs, clust);   /* Get current sector */        fp->sect_clust = fs->sects_clust; /* Re-initialize the left sector counter */      }#if !_FS_READONLY      if (fp->flag & FA__DIRTY) {       /* Flush file I/O buffer if needed */        if (diskWrite(fs->drive, fp->buffer, fp->curr_sect, 1) != DRESULT_OK)          goto fr_error;        fp->flag &= ~FA__DIRTY;      }#endif      fp->curr_sect = sect;         /* Update current sector */      cc = btr / S_SIZ;           /* When left bytes >= S_SIZ, */      if (cc) {               /* Read maximum contiguous sectors directly */        if (cc > fp->sect_clust) cc = fp->sect_clust;        if (diskRead(fs->drive, rbuff, sect, cc) != DRESULT_OK)          goto fr_error;        fp->sect_clust -= cc - 1;        fp->curr_sect += cc - 1;        rcnt = cc * S_SIZ; continue;      }      if (diskRead(fs->drive, fp->buffer, sect, 1) != DRESULT_OK) /* Load the sector into file I/O buffer */        goto fr_error;    }    rcnt = S_SIZ - ((U16)fp->fptr & (S_SIZ - 1));       /* Copy fractional bytes from file I/O buffer */    if (rcnt > btr) rcnt = btr;    memcpy(rbuff, &fp->buffer[fp->fptr & (S_SIZ - 1)], rcnt);  }  return FR_OK;fr_error: /* Abort this file due to an unrecoverable error */  fp->flag |= FA__ERROR;  return FR_RW_ERROR;}#if !_FS_READONLY/*-----------------------------------------------------------------------*//* Write File                                                            *//*-----------------------------------------------------------------------*/FRESULT f_write (    FIL *fp,      /* Pointer to the file object */    const void *buff, /* Pointer to the data to be written */    U16 btw,      /* Number of bytes to write */    U16 *bw     /* Pointer to number of bytes written */    ){  U32 clust, sect;  U16 wcnt;  U8 cc;  FRESULT res;  const U8 *wbuff = buff;  FATFS *fs = fp->fs;  *bw = 0;  res = validate(fs, fp->id);           /* Check validity of the object */  if (res) return res;  if (fp->flag & FA__ERROR) return FR_RW_ERROR; /* Check error flag */  if (!(fp->flag & FA_WRITE)) return FR_DENIED; /* Check access mode */  if (fp->fsize + btw < fp->fsize) return FR_OK;  /* File size cannot reach 4GB */  for ( ;  btw;                 /* Repeat until all data transferred */      wbuff += wcnt, fp->fptr += wcnt, *bw += wcnt, btw -= wcnt) {    if ((fp->fptr & (S_SIZ - 1)) == 0) {    /* On the sector boundary */      if (--fp->sect_clust) {         /* Decrement left sector counter */        sect = fp->curr_sect + 1;     /* Get current sector */      } else {                /* On the cluster boundary, get next cluster */        if (fp->fptr == 0) {        /* Is top of the file */          clust = fp->org_clust;          if (clust == 0)         /* No cluster is created yet */            fp->org_clust = clust = create_chain(fs, 0);  /* Create a new cluster chain */        } else {              /* Middle or end of file */          clust = create_chain(fs, fp->curr_clust);     /* Trace or streach cluster chain */        }        if (clust == 0) break;        /* Disk full */        if (clust == 1 || clust >= fs->max_clust) goto fw_error;        fp->curr_clust = clust;       /* Current cluster */        sect = clust2sect(fs, clust);   /* Get current sector */        fp->sect_clust = fs->sects_clust; /* Re-initialize the left sector counter */      }      if (fp->flag & FA__DIRTY) {       /* Flush file I/O buffer if needed */        if (diskWrite(fs->drive, fp->buffer, fp->curr_sect, 1) != DRESULT_OK)          goto fw_error;        fp->flag &= ~FA__DIRTY;      }      fp->curr_sect = sect;         /* Update current sector */      cc = btw / S_SIZ;           /* When left bytes >= S_SIZ, */      if (cc) {               /* Write maximum contiguous sectors directly */        if (cc > fp->sect_clust) cc = fp->sect_clust;        if (diskWrite(fs->drive, wbuff, sect, cc) != DRESULT_OK)          goto fw_error;        fp->sect_clust -= cc - 1;        fp->curr_sect += cc - 1;        wcnt = cc * S_SIZ; continue;      }      if (fp->fptr < fp->fsize &&       /* Fill sector buffer with file data if needed */          diskRead(fs->drive, fp->buffer, sect, 1) != DRESULT_OK)        goto fw_error;    }    wcnt = S_SIZ - ((U16)fp->fptr & (S_SIZ - 1)); /* Copy fractional bytes to file I/O buffer */    if (wcnt > btw) wcnt = btw;    memcpy(&fp->buffer[fp->fptr & (S_SIZ - 1)], wbuff, wcnt);    fp->flag |= FA__DIRTY;  }  if (fp->fptr > fp->fsize) fp->fsize = fp->fptr; /* Update file size if needed */  fp->flag |= FA__WRITTEN;            /* Set file changed flag */  return FR_OK;fw_error: /* Abort this file due to an unrecoverable error */  fp->flag |= FA__ERROR;  return FR_RW_ERROR;}/*-----------------------------------------------------------------------*//* Synchronize between File and Disk                                     *//*-----------------------------------------------------------------------*/FRESULT f_sync (    FIL *fp   /* Pointer to the file object */    ){  U32 tim;  U8 *dir;  FRESULT res;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -