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

📄 ff.c

📁 最新的LPC214X FATFS驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
////  $Id: ff.c 42 2008-10-04 18:40:36Z jcw $//  $Revision: 42 $//  $Author: jcw $//  $Date: 2008-10-04 14:40:36 -0400 (Sat, 04 Oct 2008) $//  $HeadURL: http://tinymicros.com/svn_public/arm/lpc2148_demo/trunk/fatfs/ff.c $///*--------------------------------------------------------------------------/  /  FatFs - FAT file system module  R0.04b                    (C)ChaN, 2007  /---------------------------------------------------------------------------/  / The FatFs module is an experimenal project to implement FAT file system to  / cheap microcontrollers. This is a free software and is opened for education,  / research and development under license policy of following trems.  /  /  Copyright (C) 2007, ChaN, all right reserved.  /  / * The FatFs module is a free software and there is no warranty.  / * You can use, modify and/or redistribute it for personal, non-profit or  /   profit use without any restriction under your responsibility.  / * Redistributions of source code must retain the above copyright notice.  /  /---------------------------------------------------------------------------/  /  Feb 26, 2006  R0.00  Prototype.  /  Apr 29, 2006  R0.01  First stable version.  /  Jun 01, 2006  R0.02  Added FAT12 support.  /                       Removed unbuffered mode.  /                       Fixed a problem on small (<32M) patition.  /  Jun 10, 2006  R0.02a Added a configuration option (_FS_MINIMUM).  /  Sep 22, 2006  R0.03  Added f_rename().  /                       Changed option _FS_MINIMUM to _FS_MINIMIZE.  /  Dec 11, 2006  R0.03a Improved cluster scan algolithm to write files fast.  /                       Fixed f_mkdir() creates incorrect directory on FAT32.  /  Feb 04, 2007  R0.04  Supported multiple drive system.  /                       Changed some interfaces for multiple drive system.  /                       Changed f_mountdrv() to f_mount().  /                       Added f_mkfs().  /  Apr 01, 2007  R0.04a Supported multiple partitions on a plysical drive.  /                       Added a capability of extending file size to f_lseek().  /                       Added minimization level 3.  /                       Fixed an endian sensitive code in f_mkfs().  /  May 05, 2007  R0.04b Added a configuration option _USE_NTFLAG.  /                       Added FSInfo support.  /                       Fixed DBCS name can result FR_INVALID_NAME.  /                       Fixed short seek (<= csize) collapses the file object.  /---------------------------------------------------------------------------*/#include <stdio.h> // ####include <string.h>#include "ff.h"     /* FatFs declarations */#include "disk.h"   /* Include file for user provided disk functions *//*--------------------------------------------------------------------------  Module Private Functions  ---------------------------------------------------------------------------*/static FATFS *FatFs [_DRIVES]; /* Pointer to the file system objects (logical drives) */static U16 fsid;        /* File system mount ID *//*-----------------------------------------------------------------------*//* Change window offset                                                  *//*-----------------------------------------------------------------------*/staticBOOL move_window (    /* TRUE: successful, FALSE: failed */    FATFS *fs,      /* File system object */    U32 sector    /* Sector number to make apperance in the fs->win[] */    )           /* Move to zero only writes back dirty window */{  U32 wsect;  wsect = fs->winsect;  if (wsect != sector) {  /* Changed current window */#if _FS_READONLY == 0    U8 n;    if (fs->winflag) {  /* Write back dirty window if needed */      if (diskWrite(fs->drive, fs->win, wsect, 1) != DRESULT_OK)        return FALSE;      fs->winflag = 0;      if (wsect < (fs->fatbase + fs->sects_fat)) {  /* In FAT area */        for (n = fs->n_fats; n >= 2; n--) { /* Refrect the change to FAT copy */          wsect += fs->sects_fat;          diskWrite(fs->drive, fs->win, wsect, 1);        }      }    }#endif    if (sector) {      if (diskRead(fs->drive, fs->win, sector, 1) != DRESULT_OK)        return FALSE;      fs->winsect = sector;    }  }  return TRUE;}/*-----------------------------------------------------------------------*//* Clean-up cached data                                                  *//*-----------------------------------------------------------------------*/#if _FS_READONLY == 0staticFRESULT sync (      /* FR_OK: successful, FR_RW_ERROR: failed */    FATFS *fs     /* File system object */    ){  fs->winflag = 1;  if (!move_window(fs, 0)) return FR_RW_ERROR;#if _USE_FSINFO  if (fs->fs_type == FS_FAT32 && fs->fsi_flag) {    /* Update FSInfo sector if needed */    fs->winsect = 0;    memset(fs->win, 0, 512);    ST_U16(&fs->win[BS_55AA], 0xAA55);    ST_U32(&fs->win[FSI_LeadSig], 0x41615252);    ST_U32(&fs->win[FSI_StrucSig], 0x61417272);    ST_U32(&fs->win[FSI_Free_Count], fs->free_clust);    ST_U32(&fs->win[FSI_Nxt_Free], fs->last_clust);    diskWrite(0, fs->win, fs->fsi_sector, 1);    fs->fsi_flag = 0;  }#endif  if (diskIoctl(fs->drive, IOCTL_CTRL_SYNC, NULL) != DRESULT_OK) return FR_RW_ERROR;  return FR_OK;}#endif/*-----------------------------------------------------------------------*//* Get a cluster status                                                  *//*-----------------------------------------------------------------------*/staticU32 get_cluster (   /* 0,>=2: successful, 1: failed */    FATFS *fs,      /* File system object */    U32 clust     /* Cluster# to get the link information */    ){  U16 wc, bc;  U32 fatsect;  if (clust >= 2 && clust < fs->max_clust) {    /* Valid cluster# */    fatsect = fs->fatbase;    switch (fs->fs_type) {      case FS_FAT12 :        bc = (U16)clust * 3 / 2;        if (!move_window(fs, fatsect + (bc / S_SIZ))) break;        wc = fs->win[bc & (S_SIZ - 1)]; bc++;        if (!move_window(fs, fatsect + (bc / S_SIZ))) break;        wc |= (U16)fs->win[bc & (S_SIZ - 1)] << 8;        return (clust & 1) ? (wc >> 4) : (wc & 0xFFF);      case FS_FAT16 :        if (!move_window(fs, fatsect + (clust / (S_SIZ / 2)))) break;        return LD_U16(&fs->win[((U16)clust * 2) & (S_SIZ - 1)]);      case FS_FAT32 :        if (!move_window(fs, fatsect + (clust / (S_SIZ / 4)))) break;        return LD_U32(&fs->win[((U16)clust * 4) & (S_SIZ - 1)]) & 0x0FFFFFFF;    }  }  return 1; /* There is no cluster information, or an error occured */}/*-----------------------------------------------------------------------*//* Change a cluster status                                               *//*-----------------------------------------------------------------------*/#if _FS_READONLY == 0staticBOOL put_cluster (    /* TRUE: successful, FALSE: failed */    FATFS *fs,      /* File system object */    U32 clust,    /* Cluster# to change */    U32 val     /* New value to mark the cluster */    ){  U16 bc;  U8 *p;  U32 fatsect;  fatsect = fs->fatbase;  switch (fs->fs_type) {    case FS_FAT12 :      bc = (U16)clust * 3 / 2;      if (!move_window(fs, fatsect + (bc / S_SIZ))) return FALSE;      p = &fs->win[bc & (S_SIZ - 1)];      *p = (clust & 1) ? ((*p & 0x0F) | ((U8)val << 4)) : (U8)val;      bc++;      fs->winflag = 1;       if (!move_window(fs, fatsect + (bc / S_SIZ))) return FALSE;      p = &fs->win[bc & (S_SIZ - 1)];      *p = (clust & 1) ? (U8)(val >> 4) : ((*p & 0xF0) | ((U8)(val >> 8) & 0x0F));      break;    case FS_FAT16 :      if (!move_window(fs, fatsect + (clust / (S_SIZ / 2)))) return FALSE;      ST_U16(&fs->win[((U16)clust * 2) & (S_SIZ - 1)], (U16)val);      break;    case FS_FAT32 :      if (!move_window(fs, fatsect + (clust / (S_SIZ / 4)))) return FALSE;      ST_U32(&fs->win[((U16)clust * 4) & (S_SIZ - 1)], val);      break;    default :      return FALSE;  }  fs->winflag = 1;  return TRUE;}#endif /* !_FS_READONLY *//*-----------------------------------------------------------------------*//* Remove a cluster chain                                                *//*-----------------------------------------------------------------------*/#if _FS_READONLY == 0staticBOOL remove_chain (   /* TRUE: successful, FALSE: failed */    FATFS *fs,      /* File system object */    U32 clust     /* Cluster# to remove chain from */    ){  U32 nxt;  while (clust >= 2 && clust < fs->max_clust) {    nxt = get_cluster(fs, clust);    if (nxt == 1) return FALSE;    if (!put_cluster(fs, clust, 0)) return FALSE;    if (fs->free_clust != 0xFFFFFFFF) {      fs->free_clust++;#if _USE_FSINFO      fs->fsi_flag = 1;#endif    }    clust = nxt;  }  return TRUE;}#endif/*-----------------------------------------------------------------------*//* Stretch or create a cluster chain                                     *//*-----------------------------------------------------------------------*/#if _FS_READONLY == 0staticU32 create_chain (  /* 0: no free cluster, 1: error, >=2: new cluster number */    FATFS *fs,      /* File system object */    U32 clust     /* Cluster# to stretch, 0 means create new */    ){  U32 cstat, ncl, scl, mcl = fs->max_clust;  if (clust == 0) {   /* Create new chain */    scl = fs->last_clust;     /* Get suggested start point */    if (scl == 0 || scl >= mcl) scl = 1;  }  else {          /* Stretch existing chain */    cstat = get_cluster(fs, clust); /* Check the cluster status */    if (cstat < 2) return 1;    /* It is an invalid cluster */    if (cstat < mcl) return cstat;  /* It is already followed by next cluster */    scl = clust;  }  ncl = scl;        /* Start cluster */  for (;;) {    ncl++;              /* Next cluster */    if (ncl >= mcl) {       /* Wrap around */      ncl = 2;      if (ncl > scl) return 0;  /* No free custer */    }    cstat = get_cluster(fs, ncl); /* Get the cluster status */    if (cstat == 0) break;      /* Found a free cluster */    if (cstat == 1) return 1;   /* Any error occured */    if (ncl == scl) return 0;   /* No free custer */  }  if (!put_cluster(fs, ncl, 0x0FFFFFFF)) return 1;    /* Mark the new cluster "in use" */  if (clust && !put_cluster(fs, clust, ncl)) return 1;  /* Link it to previous one if needed */  fs->last_clust = ncl;       /* Update fsinfo */  if (fs->free_clust != 0xFFFFFFFF) {    fs->free_clust--;#if _USE_FSINFO    fs->fsi_flag = 1;#endif  }  return ncl;   /* Return new cluster number */}#endif /* !_FS_READONLY *//*-----------------------------------------------------------------------*//* Get sector# from cluster#                                             *//*-----------------------------------------------------------------------*/staticU32 clust2sect (  /* !=0: sector number, 0: failed - invalid cluster# */    FATFS *fs,    /* File system object */    U32 clust   /* Cluster# to be converted */    ){  clust -= 2;  if (clust >= (fs->max_clust - 2)) return 0;   /* Invalid cluster# */  return clust * fs->sects_clust + fs->database;}/*-----------------------------------------------------------------------*//* Move directory pointer to next                                        *//*-----------------------------------------------------------------------*/staticBOOL next_dir_entry ( /* TRUE: successful, FALSE: could not move next */    DIR *dirobj     /* Pointer to directory object */    ){  U32 clust;  U16 idx;  FATFS *fs = dirobj->fs;  idx = dirobj->index + 1;  if ((idx & ((S_SIZ - 1) / 32)) == 0) {    /* Table sector changed? */    dirobj->sect++;     /* Next sector */    if (!dirobj->clust) {   /* In static table */      if (idx >= fs->n_rootdir) return FALSE; /* Reached to end of table */    } else {          /* In dynamic table */      if (((idx / (S_SIZ / 32)) & (fs->sects_clust - 1)) == 0) {  /* Cluster changed? */        clust = get_cluster(fs, dirobj->clust);   /* Get next cluster */        if (clust < 2 || clust >= fs->max_clust)  /* Reached to end of table */          return FALSE;        dirobj->clust = clust;        /* Initialize for new cluster */        dirobj->sect = clust2sect(fs, clust);      }    }  }  dirobj->index = idx;  /* Lower 4 bit of dirobj->index indicates offset in dirobj->sect */  return TRUE;}

⌨️ 快捷键说明

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