浏览代码

Fix allocation algorithm

Bill Greiman 6 年之前
父节点
当前提交
f0c65da000
共有 6 个文件被更改,包括 54 次插入37 次删除
  1. 2 2
      examples/AnalogBinLogger/AnalogBinLogger.ino
  2. 1 1
      library.properties
  3. 10 0
      src/FatLib/FatApiConstants.h
  4. 39 32
      src/FatLib/FatVolume.cpp
  5. 1 1
      src/FatLib/FatVolume.h
  6. 1 1
      src/SdFat.h

+ 2 - 2
examples/AnalogBinLogger/AnalogBinLogger.ino

@@ -436,7 +436,7 @@ void binaryToCsv() {
     return;
   }
   binFile.rewind();
-  if (!binFile.read(&buf , 512) == 512) {
+  if (binFile.read(&buf , 512) != 512) {
     error("Read metadata failed");
   }
   // Create a new csv file.
@@ -517,7 +517,7 @@ void checkOverrun() {
   binFile.rewind();
   Serial.println();
   Serial.println(F("Checking overrun errors - type any character to stop"));
-  if (!binFile.read(&buf , 512) == 512) {
+  if (binFile.read(&buf , 512) != 512) {
     error("Read metadata failed");
   }
   bn++;

+ 1 - 1
library.properties

@@ -1,5 +1,5 @@
 name=SdFat
-version=1.0.7
+version=1.0.8
 author=Bill Greiman <fat16lib@sbcglobal.net>
 maintainer=Bill Greiman <fat16lib@sbcglobal.net>
 sentence=FAT16/FAT32 file system for SD cards.

+ 10 - 0
src/FatLib/FatApiConstants.h

@@ -24,6 +24,16 @@
  */
 #ifndef FatApiConstants_h
 #define FatApiConstants_h
+// Temp fix for particle mesh.
+#ifdef O_RDONLY
+#undef O_RDONLY
+#endif  // O_RDONLY
+#ifdef O_RDWR
+#undef O_RDWR
+#endif  // O_RDWR
+#ifdef O_WRONLY
+#undef O_WRONLY
+#endif  // O_WRONLY
 //------------------------------------------------------------------------------
 // use the gnu style oflag in open()
 /** open() oflag for reading */

+ 39 - 32
src/FatLib/FatVolume.cpp

@@ -71,14 +71,33 @@ fail:
 }
 //------------------------------------------------------------------------------
 bool FatVolume::allocateCluster(uint32_t current, uint32_t* next) {
-  uint32_t find = current ? current : m_allocSearchStart;
-  uint32_t start = find;
+  uint32_t find;
+  bool setStart;
+  if (m_allocSearchStart < current) {
+    // Try to keep file contiguous. Start just after current cluster.
+    find = current;
+    setStart = false;
+  } else {
+    find = m_allocSearchStart;
+    setStart = true;
+  }
   while (1) {
     find++;
-    // If at end of FAT go to beginning of FAT.
     if (find > m_lastCluster) {
-      find = 2;
+      if (setStart) {
+        // Can't find space, checked all clusters.
+        DBG_FAIL_MACRO;
+        goto fail;        
+      }
+      find = m_allocSearchStart;
+      setStart = true;
+      continue;
     }
+    if (find == current) {
+      // Can't find space, already searched clusters after current.
+      DBG_FAIL_MACRO;
+      goto fail;      
+    }    
     uint32_t f;
     int8_t fg = fatGet(find, &f);
     if (fg < 0) {
@@ -88,27 +107,22 @@ bool FatVolume::allocateCluster(uint32_t current, uint32_t* next) {
     if (fg && f == 0) {
       break;
     }
-    if (find == start) {
-      // Can't find space checked all clusters.
-      DBG_FAIL_MACRO;
-      goto fail;
-    }
   }
-  // mark end of chain
+  if (setStart) {
+    m_allocSearchStart = find;
+  }
+  // Mark end of chain.
   if (!fatPutEOC(find)) {
     DBG_FAIL_MACRO;
     goto fail;
   }
   if (current) {
-    // link clusters
+    // Link clusters.
     if (!fatPut(current, find)) {
       DBG_FAIL_MACRO;
       goto fail;
     }
-  } else {
-    // Remember place for search start.
-    m_allocSearchStart = find;
-  }
+  }   
   updateFreeClusterCount(-1);
   *next = find;
   return true;
@@ -126,14 +140,14 @@ bool FatVolume::allocContiguous(uint32_t count, uint32_t* firstCluster) {
   // end of group
   uint32_t endCluster;
   // Start at cluster after last allocated cluster.
-  uint32_t startCluster = m_allocSearchStart;
-  endCluster = bgnCluster = startCluster + 1;
+  endCluster = bgnCluster = m_allocSearchStart + 1;
 
   // search the FAT for free clusters
   while (1) {
-    // If past end - start from beginning of FAT.
     if (endCluster > m_lastCluster) {
-      bgnCluster = endCluster = 2;
+      // Can't find space.
+      DBG_FAIL_MACRO;
+      goto fail;
     }
     uint32_t f;
     int8_t fg = fatGet(endCluster, &f);
@@ -142,29 +156,22 @@ bool FatVolume::allocContiguous(uint32_t count, uint32_t* firstCluster) {
       goto fail;
     }
     if (f || fg == 0) {
-      // cluster in use try next cluster as bgnCluster
-      bgnCluster = endCluster + 1;
-
       // don't update search start if unallocated clusters before endCluster.
       if (bgnCluster != endCluster) {
         setStart = false;
       }
+      // cluster in use try next cluster as bgnCluster
+      bgnCluster = endCluster + 1;
     } else if ((endCluster - bgnCluster + 1) == count) {
       // done - found space
       break;
     }
-    // Can't find space if all clusters checked.
-    if (startCluster == endCluster) {
-      DBG_FAIL_MACRO;
-      goto fail;
-    }
     endCluster++;
   }
-  // remember possible next free cluster
+  // Remember possible next free cluster.
   if (setStart) {
-    m_allocSearchStart = endCluster + 1;
+    m_allocSearchStart = endCluster;
   }
-
   // mark end of chain
   if (!fatPutEOC(endCluster)) {
     DBG_FAIL_MACRO;
@@ -355,8 +362,8 @@ bool FatVolume::freeChain(uint32_t cluster) {
     // Add one to count of free clusters.
     updateFreeClusterCount(1);
 
-    if (cluster < m_allocSearchStart) {
-      m_allocSearchStart = cluster;
+    if (cluster <= m_allocSearchStart) {
+      m_allocSearchStart = cluster - 1;
     }
     cluster = next;
   } while (fg);

+ 1 - 1
src/FatLib/FatVolume.h

@@ -255,7 +255,7 @@ class FatVolume {
    *
    * \param[in] n cluster number.
    * \param[out] v value of entry
-   * \return true for success or false for failure
+   * \return -1 error, 0 EOC, else 1.
    */
   int8_t dbgFat(uint32_t n, uint32_t* v) {
     return fatGet(n, v);

+ 1 - 1
src/SdFat.h

@@ -37,7 +37,7 @@
 #endif  // INCLUDE_SDIOS
 //------------------------------------------------------------------------------
 /** SdFat version */
-#define SD_FAT_VERSION "1.0.7"
+#define SD_FAT_VERSION "1.0.8"
 //==============================================================================
 /**
  * \class SdBaseFile