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

📄 ff.c

📁 最新的LPC214X FATFS驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/*-----------------------------------------------------------------------*//* Get file status from directory entry                                  *//*-----------------------------------------------------------------------*/#if _FS_MINIMIZE <= 1staticvoid get_fileinfo (   /* No return code */    FILINFO *finfo,   /* Ptr to store the file information */    const U8 *dir   /* Ptr to the directory entry */    ){  U8 n, c, a;  char *p;  p = &finfo->fname[0];  a = _USE_NTFLAG ? dir[DIR_NTres] : 0;   /* NT flag */  for (n = 0; n < 8; n++) { /* Convert file name (body) */    c = dir[n];    if (c == ' ') break;    if (c == 0x05) c = 0xE5;    if (a & 0x08 && c >= 'A' && c <= 'Z') c += 0x20;    *p++ = c;  }  if (dir[8] != ' ') {    /* Convert file name (extension) */    *p++ = '.';    for (n = 8; n < 11; n++) {      c = dir[n];      if (c == ' ') break;      if (a & 0x10 && c >= 'A' && c <= 'Z') c += 0x20;      *p++ = c;    }  }  *p = '\0';  finfo->fattrib = dir[DIR_Attr];         /* Attribute */  finfo->fsize = LD_U32(&dir[DIR_FileSize]);  /* Size */  finfo->fdate = LD_U16(&dir[DIR_WrtDate]);   /* Date */  finfo->ftime = LD_U16(&dir[DIR_WrtTime]);   /* Time */}#endif /* _FS_MINIMIZE <= 1 *//*-----------------------------------------------------------------------*//* Pick a paragraph and create the name in format of directory entry     *//*-----------------------------------------------------------------------*/staticchar make_dirfile (     /* 1: error - detected an invalid format, '\0'or'/': next character */    const char **path,    /* Pointer to the file path pointer */    char *dirname     /* Pointer to directory name buffer {Name(8), Ext(3), NT flag(1)} */    ){  U8 n, t, c, a, b;  memset(dirname, ' ', 8+3);  /* Fill buffer with spaces */  a = 0; b = 0x18;          /* NT flag */  n = 0; t = 8;  for (;;) {    c = *(*path)++;    if (c == '\0' || c == '/') {    /* Reached to end of str or directory separator */      if (n == 0) break;      dirname[11] = _USE_NTFLAG ? (a & b) : 0;      return c;    }    if (c <= ' ' || c == 0x7F) break;   /* Reject invisible chars */    if (c == '.') {      if (!(a & 1) && n >= 1 && n <= 8) { /* Enter extension part */        n = 8; t = 11; continue;      }      break;    }    if (_USE_SJIS &&        ((c >= 0x81 && c <= 0x9F) ||  /* Accept S-JIS code */         (c >= 0xE0 && c <= 0xFC))) {      if (n == 0 && c == 0xE5)    /* Change heading \xE5 to \x05 */        c = 0x05;      a ^= 1; goto md_l2;    }    if (c == '"') break;        /* Reject " */    if (c <= ')') goto md_l1;     /* Accept ! # $ % & ' ( ) */    if (c <= ',') break;        /* Reject * + , */    if (c <= '9') goto md_l1;     /* Accept - 0-9 */    if (c <= '?') break;        /* Reject : ; < = > ? */    if (!(a & 1)) { /* These checks are not applied to S-JIS 2nd byte */      if (c == '|') break;      /* Reject | */      if (c >= '[' && c <= ']') break;/* Reject [ \ ] */      if (_USE_NTFLAG && c >= 'A' && c <= 'Z')        (t == 8) ? (b &= ~0x08) : (b &= ~0x10);      if (c >= 'a' && c <= 'z') {   /* Convert to upper case */        c -= 0x20;        if (_USE_NTFLAG) (t == 8) ? (a |= 0x08) : (a |= 0x10);      }    }md_l1:    a &= ~1;md_l2:    if (n >= t) break;    dirname[n++] = c;  }  return 1;}/*-----------------------------------------------------------------------*//* Trace a file path                                                     *//*-----------------------------------------------------------------------*/staticFRESULT trace_path (  /* FR_OK(0): successful, !=0: error code */    DIR *dirobj,    /* Pointer to directory object to return last directory */    char *fn,     /* Pointer to last segment name to return {file(8),ext(3),attr(1)} */    const char *path, /* Full-path string to trace a file or directory */    U8 **dir      /* Directory pointer in Win[] to retutn */    ){  U32 clust;  char ds;  U8 *dptr = NULL;  FATFS *fs = dirobj->fs; /* Get logical drive from the given DIR structure */  /* Initialize directory object */  clust = fs->dirbase;  if (fs->fs_type == FS_FAT32) {    dirobj->clust = dirobj->sclust = clust;    dirobj->sect = clust2sect(fs, clust);  } else {    dirobj->clust = dirobj->sclust = 0;    dirobj->sect = clust;  }  dirobj->index = 0;  if (*path == '\0') {          /* Null path means the root directory */    *dir = NULL; return FR_OK;  }  for (;;) {    ds = make_dirfile(&path, fn);     /* Get a paragraph into fn[] */    if (ds == 1) return FR_INVALID_NAME;    for (;;) {      if (!move_window(fs, dirobj->sect)) return FR_RW_ERROR;      dptr = &fs->win[(dirobj->index & ((S_SIZ - 1) / 32)) * 32]; /* Pointer to the directory entry */      if (dptr[DIR_Name] == 0)            /* Has it reached to end of dir? */        return !ds ? FR_NO_FILE : FR_NO_PATH;      if (dptr[DIR_Name] != 0xE5            /* Matched? */          && !(dptr[DIR_Attr] & AM_VOL)          && !memcmp(&dptr[DIR_Name], fn, 8+3) ) break;      if (!next_dir_entry(dirobj))          /* Next directory pointer */        return !ds ? FR_NO_FILE : FR_NO_PATH;    }    if (!ds) { *dir = dptr; return FR_OK; }       /* Matched with end of path */    if (!(dptr[DIR_Attr] & AM_DIR)) return FR_NO_PATH;  /* Cannot trace because it is a file */    clust = ((U32)LD_U16(&dptr[DIR_FstClusHI]) << 16) | LD_U16(&dptr[DIR_FstClusLO]); /* Get cluster# of the directory */    dirobj->clust = dirobj->sclust = clust;       /* Restart scanning at the new directory */    dirobj->sect = clust2sect(fs, clust);    dirobj->index = 2;  }}/*-----------------------------------------------------------------------*//* Reserve a directory entry                                             *//*-----------------------------------------------------------------------*/#if !_FS_READONLYstaticFRESULT reserve_direntry (  /* FR_OK: successful, FR_DENIED: no free entry, FR_RW_ERROR: a disk error occured */    DIR *dirobj,      /* Target directory to create new entry */    U8 **dir        /* Pointer to pointer to created entry to retutn */    ){  U32 clust, sector;  U8 c, n, *dptr;  FATFS *fs = dirobj->fs;  /* Re-initialize directory object */  clust = dirobj->sclust;  if (clust) {  /* Dyanmic directory table */    dirobj->clust = clust;    dirobj->sect = clust2sect(fs, clust);  } else {    /* Static directory table */    dirobj->sect = fs->dirbase;  }  dirobj->index = 0;  do {    if (!move_window(fs, dirobj->sect)) return FR_RW_ERROR;    dptr = &fs->win[(dirobj->index & ((S_SIZ - 1) / 32)) * 32]; /* Pointer to the directory entry */    c = dptr[DIR_Name];    if (c == 0 || c == 0xE5) {      /* Found an empty entry! */      *dir = dptr; return FR_OK;    }  } while (next_dir_entry(dirobj));       /* Next directory pointer */  /* Reached to end of the directory table */  /* Abort when static table or could not stretch dynamic table */  if (!clust || !(clust = create_chain(fs, dirobj->clust))) return FR_DENIED;  if (clust == 1 || !move_window(fs, 0)) return FR_RW_ERROR;  fs->winsect = sector = clust2sect(fs, clust);   /* Cleanup the expanded table */  memset(fs->win, 0, S_SIZ);  for (n = fs->sects_clust; n; n--) {    if (diskWrite(fs->drive, fs->win, sector, 1) != DRESULT_OK)      return FR_RW_ERROR;    sector++;  }  fs->winflag = 1;  *dir = fs->win;  return FR_OK;}#endif /* !_FS_READONLY *//*-----------------------------------------------------------------------*//* Load boot record and check if it is a FAT boot record                 *//*-----------------------------------------------------------------------*/staticU8 check_fs (   /* 0:The FAT boot record, 1:Valid boot record but not an FAT, 2:Not a boot record or error */    FATFS *fs,    /* File system object */    U32 sect    /* Sector# (lba) to check if it is a FAT boot record or not */    ){  if (diskRead(fs->drive, fs->win, sect, 1) != DRESULT_OK)  /* Load boot record */    return 2;  if (LD_U16(&fs->win[BS_55AA]) != 0xAA55)        /* Check record signature (always offset 510) */    return 2;  if (!memcmp(&fs->win[BS_FilSysType], "FAT", 3))     /* Check FAT signature */    return 0;  if (!memcmp(&fs->win[BS_FilSysType32], "FAT32", 5) && !(fs->win[BPB_ExtFlags] & 0x80))    return 0;  return 1;}/*-----------------------------------------------------------------------*//* Make sure that the file system is valid                               *//*-----------------------------------------------------------------------*/staticFRESULT auto_mount (    /* FR_OK(0): successful, !=0: any error occured */    const char **path,    /* Pointer to pointer to the path name (drive number) */    FATFS **rfs,      /* Pointer to pointer to the found file system object */    U8 chk_wp       /* !=0: Check media write protection for wrinting fuctions */    ){  U8 drv, fmt, *tbl;  DSTATUS stat;  U32 bootsect, fatsize, totalsect, maxclust;  const char *p = *path;  FATFS *fs;  /* Get drive number from the path name */  while (*p == ' ') p++;    /* Strip leading spaces */  drv = p[0] - '0';     /* Is there a drive number? */  if (drv <= 9 && p[1] == ':')    p += 2;     /* Found a drive number, get and strip it */  else    drv = 0;    /* No drive number is given, select drive 0 in default */  if (*p == '/') p++; /* Strip heading slash */  *path = p;      /* Return pointer to the path name */  /* Check if the drive number is valid or not */  if (drv >= _DRIVES) return FR_INVALID_DRIVE;  /* Is the drive number valid? */  if (!(fs = FatFs[drv])) return FR_NOT_ENABLED;  /* Is the file system object registered? */  *rfs = fs;      /* Returen pointer to the corresponding file system object */  /* Check if the logical drive has been mounted or not */  if (fs->fs_type) {    stat = diskStatus(fs->drive);    if (!(stat & DSTATUS_NOINIT)) {       /* If the physical drive is kept initialized */#if !_FS_READONLY      if (chk_wp && (stat & DSTATUS_PROTECT)) /* Check write protection if needed */        return FR_WRITE_PROTECTED;#endif      return FR_OK;           /* The file system object is valid */    }  }  /* The logical drive has not been mounted, following code attempts to mount the logical drive */  memset(fs, 0, sizeof(FATFS));   /* Clean-up the file system object */  fs->drive = LD2PD(drv);       /* Bind the logical drive and a physical drive */  stat = diskInitialize (fs->drive);  /* Initialize low level disk I/O layer */  if (stat & DSTATUS_NOINIT)        /* Check if the drive is ready */    return FR_NOT_READY;#if S_MAX_SIZ > 512           /* Check disk sector size */  if (diskIoctl(drv, IOCTL_GET_SECTOR_SIZE, &S_SIZ) != DRESULT_OK || S_SIZ > S_MAX_SIZ)    return FR_NO_FILESYSTEM;#endif#if !_FS_READONLY  if (chk_wp && (stat & DSTATUS_PROTECT)) /* Check write protection if needed */    return FR_WRITE_PROTECTED;#endif  /* Search FAT partition on the drive */  fmt = check_fs(fs, bootsect = 0); /* Check sector 0 as an SFD format */  if (fmt == 1) {           /* Not a FAT boot record, it may be patitioned */    /* Check a partition listed in top of the partition table */    tbl = &fs->win[MBR_Table + LD2PT(drv) * 16];  /* Partition table */    if (tbl[4]) {               /* Is the partition existing? */      bootsect = LD_U32(&tbl[8]);     /* Partition offset in LBA */      fmt = check_fs(fs, bootsect);     /* Check the partition */    }  }  if (fmt || LD_U16(&fs->win[BPB_BytsPerSec]) != S_SIZ) /* No valid FAT patition is found */    return FR_NO_FILESYSTEM;  /* Initialize the file system object */  fatsize = LD_U16(&fs->win[BPB_FATSz16]);      /* Number of sectors per FAT */  if (!fatsize) fatsize = LD_U32(&fs->win[BPB_FATSz32]);  fs->sects_fat = fatsize;  fs->n_fats = fs->win[BPB_NumFATs];          /* Number of FAT copies */  fatsize *= fs->n_fats;                /* (Number of sectors in FAT area) */  fs->fatbase = bootsect + LD_U16(&fs->win[BPB_RsvdSecCnt]); /* FAT start sector (lba) */  fs->sects_clust = fs->win[BPB_SecPerClus];      /* Number of sectors per cluster */  fs->n_rootdir = LD_U16(&fs->win[BPB_RootEntCnt]); /* Nmuber of root directory entries */  totalsect = LD_U16(&fs->win[BPB_TotSec16]);   /* Number of sectors on the file system */  if (!totalsect) totalsect = LD_U32(&fs->win[BPB_TotSec32]);#if 0  //  //  Patch from David Johnson  //  sectsize = LD_U16(&fs->win[BPB_BytsPerSec]);  rootdirsect = ((fs->n_rootdir * 32) + (sectsize - 1)) / sectsize;  if ((((fs->n_rootdir * 32) + (sectsize - 1)) % sectsize) > 0)    rootdirsect++;  datasec = totalsect - (LD_U16(&fs->win[BPB_RsvdSecCnt]) + fatsize + rootdirsect);  clustercnt = datasec / fs->sects_clust;  fs->max_clust = clustercnt + 1;  fmt = FS_FAT12;  if (clustercnt >= 4085) fmt = FS_FAT16;  if (clustercnt >= 65525) fmt = FS_FAT32;#else  fs->max_clust = maxclust = (totalsect       /* Last cluster# + 1 */      - LD_U16(&fs->win[BPB_RsvdSecCnt]) - fatsize - fs->n_rootdir / (S_SIZ/32)      ) / fs->sects_clust + 2;  fmt = FS_FAT12;                   /* Determine the FAT sub type */  if (maxclust > 0xFF7) fmt = FS_FAT16;  if (maxclust > 0xFFF7) fmt = FS_FAT32;#endif  fs->fs_type = fmt;  if (fmt == FS_FAT32)    fs->dirbase = LD_U32(&fs->win[BPB_RootClus]); /* Root directory start cluster */  else    fs->dirbase = fs->fatbase + fatsize;      /* Root directory start sector (lba) */  fs->database = fs->fatbase + fatsize + fs->n_rootdir / (S_SIZ/32);  /* Data start sector (lba) */#if !_FS_READONLY  fs->free_clust = 0xFFFFFFFF;#if _USE_FSINFO  /* Load fsinfo sector if needed */  if (fmt == FS_FAT32) {

⌨️ 快捷键说明

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