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

📄 fs_fat.c

📁 keil arm flash fs 最新版 在Keil arm下使用
💻 C
📖 第 1 页 / 共 5 页
字号:
   if (mmc.DskSize < 0x10000) {
      set_u16 (&ca.buf[19], mmc.DskSize);
   }
   else {
      set_u32 (&ca.buf[32], mmc.DskSize);
   }

   /* Media Type, must be the same as FAT byte 0 */
   ca.buf[21] = 0xF8;

   /* Number of Hidden Sectors */
   set_u32 (&ca.buf[28], mmc.BootRecSec);

   if (mmc.FatType != FS_FAT32) {
      /* FAT Size */
      set_u16 (&ca.buf[22], mmc.FatSize);

      /* Physical Disk Number */
      ca.buf[36] = 0x80;

      /* Boot Sig */
      ca.buf[38] = 0x29;

      /* Volume ID */
      set_u32 (&ca.buf[39], sernum);

      /* Volume Label */
      memcpy (&ca.buf[43], "NO NAME    ", 11);

      /* File System Type. */
      if (mmc.FatType == FS_FAT12) {
         memcpy (&ca.buf[54], "FAT12   ", 8);
      }
      else {
         memcpy (&ca.buf[54], "FAT16   ", 8);
      }
   }
   else {
      /* FAT32 Structure different from offset 36. */

      /* FAT Size */
      set_u32 (&ca.buf[36], mmc.FatSize);

      /* Root Cluster Number. */
      set_u32 (&ca.buf[44], 2);

      /* FSInfo */
      set_u16 (&ca.buf[48], 1);

      /* Backup Boot Sector */
      set_u16 (&ca.buf[50], 6);

      /* Physical Disk Number */
      ca.buf[64] = 0x80;

      /* Boot Sig */
      ca.buf[66] = 0x29;

      /* Volume ID */
      set_u32 (&ca.buf[67], sernum);

      /* Volume Label */
      memcpy (&ca.buf[71], "NO NAME    ", 11);

      /* File System Type. */
      memcpy (&ca.buf[82], "FAT32   ", 8);
   }

   /* Executable Marker */
   set_u16 (&ca.buf[510], 0xAA55);

   return (write_sector (mmc.BootRecSec));
}


/*--------------------------- wipe_disk -------------------------------------*/

static void wipe_disk (U32 dsize) {
   /* Clear the whole disk, write FF to all sectors. */
   U32 i,csize;

   /* Invalidate the cache. */
   ca.nwr = 0;
   ca.nrd = 0;

   /* Use the cache buffer. */
   csize = _MC_CSIZE;
   if (csize == 0) {
      csize = 1;
   }
   memset (ca.buf, 0xFF, csize * 512);

   for (i = 0; i < dsize; i += csize) {
      mmc_write_sect (i, ca.buf, csize);
   }
}


/*--------------------------- fat_free --------------------------------------*/

U32 fat_free (void) {
   /* Calculate a free space for Flash Card. */

   if (mmc.FatType == FS_RAW) {
      /* RAW File System or FAT not initialized. */
      return (0);
   }

   /* For FAT32 count only once. */
   if (mmc.FatType != FS_FAT32) {
      free_clus = count_free_clus ();
   }

   if (free_clus > mmc.DataClusCnt) {
      /* Error, something wrong. */
      return (0);
   }
   /* Return free data space in bytes. */
   return (free_clus * mmc.ClusSize);
}


/*--------------------------- fat_find_dir ----------------------------------*/

static BOOL fat_find_dir (const char *fn, IOB *fcb, U8 create) {
   /* Look for directory if it exists and leave fcb to point to directory, 
      if it does not exist and create == 1, create it. */
   U8  creating_f;
   U32 sz;

   creating_f = 0;

   while (get_dir_name (fn, name_buf, &sz) == __TRUE) {

      if (!creating_f) {
         if (find_name (name_buf, fcb, ENT_DIR) == __FALSE) {
            /* Directory does not exist. */
            if (!create) {
               /* Directory not found. */
               return (__FALSE);
            }
            /* Create requested, set creating_f flag to 1. */
            creating_f = 1;
         }
      }

      if (creating_f) {
         /* If creation of unexisting directory requested. */
         if (alloc_name (name_buf, fcb) == __FALSE) {
            /* If unable to find place to create directory. */
            return (__FALSE);
         }
         /* fcb points to unallocated entry. */
         if (write_entries (name_buf, fcb, ENT_DIR, ACT_NONE) == __FALSE) {
            /* If unable to write entries for new directory. */
            return (__FALSE);
         }
         /* Create '.' and '..' entries in created folder. */
         write_dot_entries (fcb);
      }
      fn += sz;
   }

   /* Searched directory was found or created and fcb points to it, in 
      case of creating directory fcb points to entry after ".." entry. */
   return (__TRUE);
}


/*--------------------------- fat_find_file ---------------------------------*/

BOOL fat_find_file (const char *fn, IOB *fcb) {
   /* Look for file if it exists in requested directory, the fcb is left 
      pointing to requested file entries. */

   if (mmc.FatType == FS_RAW) {
      /* RAW File System or FAT not initialized. */
      return (__FALSE);
   }

   /* Remove starting '\' if it exists. */
   if (*fn == '\\') fn++;

   /* Exit function if "fn" is not given. */
   if (*fn == 0) return(__FALSE);

   /* To force search of path from root. */
   fcb->_firstClus = 0;

   /* Search for directory. */
   if (fat_find_dir (fn, fcb, ACT_NONE) == __FALSE) {
      /* Directory does not exist. */
      return (__FALSE);
   }

   /* Search for file. */
   if (find_name (name_buf, fcb, ENT_FILE) == __FALSE) {
      /* File does not exist. */
      return (__FALSE);
   }

   /* Set _currDatSect and _currDat Clus to show to data of found file. */
   fcb->_currDatSect  = 0;
   fcb->_currDatClus  = fcb->_firstClus;

   /* If file exists. */
   return (__TRUE);
}


/*--------------------------- fat_ffind -------------------------------------*/

BOOL fat_ffind (const char *fn, FINFO *info, IOB *fcb) {
   /* Find a file or directory in requested directory. */

   if (mmc.FatType == FS_RAW) {
      /* RAW File System or FAT not initialized. */
      return (__FALSE);
   }

   /* Remove starting '\' if it exists. */
   if (*fn == '\\') fn++;

   /* Exit function if "fn" is not given. */
   if (*fn == 0) return(__FALSE);

   /* To force search of path from root. */
   fcb->_firstClus = 0;

   /* Search for directory. */
   if (fat_find_dir (fn, fcb, 0) == __FALSE) {
      /* Directory does not exist. */
      return (__FALSE);
   }

   /* Get next valid info. */
   if (get_next_info (info, fcb) == __FALSE) {
      /* No more valid infos in current directory. */
      return (__FALSE);
   }

   /* Info found. */
   return (__TRUE);
}


/*--------------------------- fat_create ------------------------------------*/

BOOL fat_create (const char *fn, IOB *fcb) {
   /* Create a file or directory in requested directory. */
   
   if (mmc.FatType == FS_RAW) {
      /* RAW File System or FAT not initialized. */
      return (__FALSE);
   }

   /* Remove starting '\' if it exists. */
   if (*fn == '\\') fn++;

   /* Exit function if "fn" is not given. */
   if (*fn == 0) return(__FALSE);

   /* To force search of path from root. */
   fcb->_firstClus = 0;

   /* Search for directory. */
   if (fat_find_dir (fn, fcb, 1) == __FALSE) {
      /* Directory does not exist and could not be created. */
      return (__FALSE);
   }

   /* File does not exist, create one. */
   if (alloc_name (name_buf, fcb) == __FALSE) {
      /* If unable to find unallocated entry to create file. */
      return (__FALSE);
   }

   /* fcb points to unallocated entry. */
   if (write_entries (name_buf, fcb, ENT_FILE, ACT_NONE) == __FALSE) {
      /* If unable to write entries for new file. */
      return (__FALSE);
   }

   /* File created. */
   return (__TRUE);
}


/*--------------------------- fat_delete ------------------------------------*/

BOOL fat_delete (const char *fn, IOB *fcb) {
   /* Delete a file or directory from requested directory. */

   if (mmc.FatType == FS_RAW) {
      /* RAW File System or FAT not initialized. */
      return (__FALSE);
   }

   /* Remove starting '\' if it exists. */
   if (*fn == '\\') fn++;

   /* Exit function if "fn" is not given. */
   if (*fn == 0) return(__FALSE);

   /* To force search of path from root. */
   fcb->_firstClus = 0;

   /* Search for directory. */
   if (fat_find_dir (fn, fcb, 0) == __FALSE) {
      /* Directory does not exist. */
      return (__FALSE);
   }
                                                        
   if (name_buf[0]) {
      /* Search for file. */
      if (find_name (name_buf, fcb, ENT_FILE) == __FALSE) {
         /* File does not exist. */
         return (__FALSE);
      }
   }
   else {
      /* We want to delete a directory, see if it is empty. */
      if (chk_dir_empty (fcb) == __FALSE) {
         /* Directory is not empty, do not delete it. */
         return (__FALSE);
      }
   }

   /* File or directory entries found and fcb points to first entry. */
   if (delete_entries (fcb, 0) == __FALSE) {
      /* If file or directory was not deleted successfully. */
      return (__FALSE);
   }

   /* File was deleted. */
   return (__TRUE);
}


/*--------------------------- fat_read --------------------------------------*/

U32 fat_read (IOB *fcb, U8 *buf, U32 len) {
   /* Read data from file at current file position. */
   U32 sect,pos,nr,rlen;

   if (mmc.FatType == FS_RAW) {
      /* RAW File System or FAT not initialized. */
      return (0);
   }
   if (fcb->fpos + len > fcb->fsize) {
      /* Check for End Of File. */
      len = fcb->fsize - fcb->fpos;
      if (len == 0) {
         /* End of File. */
         return (0);
      }
   }

   pos = fcb->fpos & 0x1FF;
   for (nr = 0; nr < len; nr += rlen) {
      sect = clus_to_sect (fcb->_currDatClus) + fcb->_currDatSect;
      /* Try to cache current cluster. */
      read_cache (sect, mmc.SecPerClus - fcb->_currDatSect);

      rlen = len - nr;
      if ((rlen + pos) > 512) {
         rlen = 512 - pos;
      }

      memcpy (&buf[nr], &ca.buf[pos], rlen);
      pos = (pos + rlen) & 0x1FF;
      if (pos == 0) {
         /* Current sector complete, get next one. */
         if (++fcb->_currDatSect == mmc.SecPerClus) {
            /* This cluster is processed, get next one. */
            fcb->_currDatSect = 0;
            set_next_clus (&fcb->_currDatClus);
         }
      }
   }
   fcb->fpos += nr;
   /* Number of characters read. */
   return (len);
}


/*--------------------------- fat_write -------------------------------------*/

BOOL fat_write (IOB *fcb, const U8 *buf, U32 len) {
   /* Write data to file at current file position. */
   U32 sect,pos,nw,wlen,clus;

   if (mmc.FatType == FS_RAW) {
      /* RAW File System or FAT not initialized. */
      return (__FALSE);
   }
   if (fcb->_firstClus == 0) {
      /* Data cluster not allocated yet. */
      if (get_free_clus (&fcb->_currDatClus) == __FALSE) {
         /* Disk Full, no free clusters found. */
         return (__FALSE);
      }
      fcb->_firstClus   = fcb->_currDatClus;
      fcb->_currDatSect = 0;
   }

   pos = fcb->fpos & 0x1FF;
   for (nw = 0; nw < len; nw += wlen) {
      wlen = len - nw;
      if ((wlen + pos) > 512) {
         wlen = 512 - pos;
      }
      sect = clus_to_sect (fcb->_currDatClus) + fcb->_currDatSect;
      if (pos != 0) {
         /* File position not 512-byte aligned. */
         read_sector (sect);
      }
      memcpy (&ca.buf[pos], &buf[nw], wlen);
      write_cache (sect);

      pos = (pos + wlen) & 0x1FF;

      if (pos == 0) {
         /* Current sector is full, get next one. */
         if (++fcb->_currDatSect == mmc.SecPerClus) {
            /* This cluster is processed, get next one. */
            fcb->_currDatSect = 0;
            clus = fcb->_currDatClus;
            if (get_free_clus (&fcb->_currDatClus) == __FALSE) {
               /* Failed to allocate a free cluster. */
               return (__FALSE);
            }
            /* Update also a FAT cluster chain. */
            write_fat_link (clus, fcb->_currDatClus);
         }
      }
   }
   fcb->fpos += nw;
   return (__TRUE);
}


/*--------------------------- fat_close_write -------------------------------*/

BOOL fat_close_write (IOB *fcb) {
   /* Close an opened file, update FAT and Directory record. */
   FILEREC last_frec;

   if (mmc.FatType == FS_RAW) {
      /* RAW File System or FAT not initialized. */
      return (__FALSE);
   }

   if (fcb->fpos > fcb->fsize) {
      /* Write an EOC marker to FAT table Cluster chain. */
      write_fat_link (fcb->_currDatClus, get_EOC());

      /* Update File Length info from Directory Entry record. */
      /* Read last entry to keep some informations from it. */
      read_last_entry  (fcb, &last_frec);
      last_frec.FirstClusHI = (U16)(fcb->_firstClus >> 16);
      last_frec.FirstClusLO = (U16)(fcb->_firstClus      );
      last_frec.FileSize    = fcb->fpos;
      /* Write updated last entry. */
      write_last_entry (fcb, &last_frec);
   }

⌨️ 快捷键说明

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