]> git.sur5r.net Git - freertos/blobdiff - FreeRTOS-Plus/Source/FreeRTOS-Plus-FAT-SL/fat_sl/common/file.c
Update FreeRTOS+FAT SL to version 1.0.1.
[freertos] / FreeRTOS-Plus / Source / FreeRTOS-Plus-FAT-SL / fat_sl / common / file.c
index ae08990b22840e642153320e6abf846ed55e704b..964b86c286757b581c32bd11a993c4fee3bce964 100644 (file)
@@ -1,13 +1,15 @@
 /*\r
- * FreeRTOS+FAT FS V1.0.0 (C) 2013 HCC Embedded\r
+ * FreeRTOS+FAT SL V1.0.1 (C) 2014 HCC Embedded\r
  *\r
  * The FreeRTOS+FAT SL license terms are different to the FreeRTOS license \r
  * terms.\r
  * \r
- * FreeRTOS+FAT SL uses a dual license model that allows the software to be used\r
- * under a pure GPL open source license (as opposed to the modified GPL licence\r
- * under which FreeRTOS is distributed) or a commercial license.  Details of \r
- * both license options follow:\r
+ * FreeRTOS+FAT SL uses a dual license model that allows the software to be used \r
+ * under a standard GPL open source license, or a commercial license.  The \r
+ * standard GPL license (unlike the modified GPL license under which FreeRTOS \r
+ * itself is distributed) requires that all software statically linked with \r
+ * FreeRTOS+FAT SL is also distributed under the same GPL V2 license terms.  \r
+ * Details of both license options follow:\r
  * \r
  * - Open source licensing -\r
  * FreeRTOS+FAT SL is a free download and may be used, modified, evaluated and\r
 #include "file.h"\r
 \r
 #include "../../version/ver_fat_sl.h"\r
-#if VER_FAT_SL_MAJOR != 3 || VER_FAT_SL_MINOR != 2\r
+#if VER_FAT_SL_MAJOR != 5 || VER_FAT_SL_MINOR != 2\r
  #error Incompatible FAT_SL version number!\r
 #endif\r
 \r
-static unsigned char _f_emptywritebuffer ( void );\r
+static unsigned char _f_stepnextsector ( void );\r
 \r
 \r
 /****************************************************************************\r
@@ -123,73 +125,77 @@ long fn_filelength ( const char * filename )
  * error code or zero if successful\r
  *\r
  ***************************************************************************/\r
-\r
-\r
-static unsigned char _f_emptywritebuffer ( void )\r
+static unsigned char _f_stepnextsector ( void )\r
 {\r
   unsigned char  ret;\r
+  unsigned char  b_alloc;\r
 \r
-  ret = _f_writeglsector( gl_file.pos.sector );\r
-  if ( ret )\r
+  b_alloc = 0;\r
+  gl_volume.fatsector = (unsigned long)-1;\r
+  if ( gl_file.startcluster == 0 )\r
   {\r
-    return ret;\r
+    b_alloc = 1;\r
   }\r
+  else\r
+  {\r
+    ++gl_file.pos.sector;\r
+    if ( gl_file.pos.sector >= gl_file.pos.sectorend )\r
+    {\r
+      unsigned long  value;\r
 \r
-  gl_file.modified = 0;\r
+      ret = _f_getclustervalue( gl_file.pos.cluster, &value );\r
+      if ( ret )\r
+      {\r
+        return ret;\r
+      }\r
 \r
-  gl_file.pos.sector++;\r
+      if ( ( value >= 2 ) && ( value < F_CLUSTER_RESERVED ) ) /*we are in chain*/\r
+      {\r
+        _f_clustertopos( value, &gl_file.pos );    /*go to next cluster*/\r
+      }\r
+      else\r
+      {\r
+        b_alloc = 1;\r
+      }\r
+    }\r
+  }\r
 \r
-  if ( gl_file.pos.sector >= gl_file.pos.sectorend )\r
+  if ( b_alloc != 0 )\r
   {\r
-    unsigned long  value;\r
+    unsigned long  nextcluster;\r
+\r
+    ret = _f_alloccluster( &nextcluster );\r
+    if ( ret )\r
+    {\r
+      return ret;\r
+    }\r
 \r
-    gl_volume.fatsector = (unsigned long)-1;\r
-    ret = _f_getclustervalue( gl_file.pos.cluster, &value );\r
+    ret = _f_setclustervalue( nextcluster, F_CLUSTER_LAST );\r
     if ( ret )\r
     {\r
       return ret;\r
     }\r
 \r
-    if ( ( value >= 2 ) && ( value < F_CLUSTER_RESERVED ) ) /*we are in chain*/\r
+    if ( gl_file.startcluster == 0 )\r
     {\r
-      gl_file.prevcluster = gl_file.pos.cluster;\r
-      _f_clustertopos( value, &gl_file.pos );    /*go to next cluster*/\r
+      gl_file.startcluster = nextcluster;\r
     }\r
     else\r
     {\r
-      unsigned long  nextcluster;\r
-\r
-      ret = _f_alloccluster( &nextcluster );\r
-      if ( ret )\r
-      {\r
-        return ret;\r
-      }\r
-\r
-      ret = _f_setclustervalue( nextcluster, F_CLUSTER_LAST );\r
-      if ( ret )\r
-      {\r
-        return ret;\r
-      }\r
-\r
       ret = _f_setclustervalue( gl_file.pos.cluster, nextcluster );\r
       if ( ret )\r
       {\r
         return ret;\r
       }\r
+    }\r
 \r
-      gl_file.prevcluster = gl_file.pos.cluster;\r
-\r
-      _f_clustertopos( nextcluster, &gl_file.pos );\r
+    _f_clustertopos( nextcluster, &gl_file.pos );\r
 \r
-      return _f_writefatsector();\r
-    }\r
+    return _f_writefatsector();\r
   }\r
 \r
-\r
   return F_NO_ERROR;\r
-} /* _f_emptywritebuffer */\r
-\r
-\r
+} /* _f_stepnextsector */\r
 \r
 \r
 /****************************************************************************\r
@@ -207,30 +213,65 @@ static unsigned char _f_extend ( long size )
   size -= gl_file.filesize;\r
   _size = (unsigned long)size;\r
 \r
-  rc = _f_getcurrsector();\r
-  if ( rc )\r
+  if ( gl_file.startcluster == 0 )\r
+  {\r
+    if ( _f_stepnextsector() )\r
+    {\r
+      return F_ERR_WRITE;\r
+    }\r
+  }\r
+  else\r
   {\r
-    return rc;\r
+    if ( ( gl_file.relpos > 0 ) && ( gl_file.relpos < F_SECTOR_SIZE ) )\r
+    {\r
+      rc = _f_getcurrsector();\r
+      if ( rc )\r
+      {\r
+        return rc;\r
+      }\r
+    }\r
   }\r
 \r
-  psp_memset( gl_sector + gl_file.relpos, 0, ( F_SECTOR_SIZE - gl_file.relpos ) );\r
-\r
-  if ( gl_file.relpos + _size > F_SECTOR_SIZE )\r
+  if ( gl_file.relpos + _size >= F_SECTOR_SIZE )\r
   {\r
-    _size -= ( F_SECTOR_SIZE - gl_file.relpos );\r
-    while ( _size )\r
+    if ( gl_file.relpos < F_SECTOR_SIZE )\r
     {\r
-      if ( _f_emptywritebuffer() )\r
+      psp_memset( gl_sector + gl_file.relpos, 0, ( F_SECTOR_SIZE - gl_file.relpos ) );\r
+      _size -= ( F_SECTOR_SIZE - gl_file.relpos );\r
+\r
+      if ( _f_writeglsector( gl_file.pos.sector ) )\r
+      {\r
+        return F_ERR_WRITE;\r
+      }\r
+    }\r
+\r
+    if ( _f_stepnextsector() )\r
+    {\r
+      return F_ERR_WRITE;\r
+    }\r
+\r
+    psp_memset( gl_sector, 0, F_SECTOR_SIZE );\r
+\r
+    while ( _size >= F_SECTOR_SIZE )\r
+    {\r
+      if ( _f_writeglsector( gl_file.pos.sector ) )\r
+      {\r
+        return F_ERR_WRITE;\r
+      }\r
+\r
+      if ( _f_stepnextsector() )\r
       {\r
         return F_ERR_WRITE;\r
       }\r
 \r
       psp_memset( gl_sector, 0, F_SECTOR_SIZE );\r
-      _size -= ( _size > F_SECTOR_SIZE ? F_SECTOR_SIZE : _size );\r
+\r
+      _size -= F_SECTOR_SIZE;\r
     }\r
   }\r
   else\r
   {\r
+    psp_memset( gl_sector + gl_file.relpos, 0, ( F_SECTOR_SIZE - gl_file.relpos ) );\r
     _size += gl_file.relpos;\r
   }\r
 \r
@@ -293,7 +334,6 @@ static unsigned char _f_fseek ( long offset )
     {\r
       gl_file.abspos = 0;\r
       gl_file.relpos = 0;\r
-      gl_file.prevcluster = 0;\r
       gl_file.pos.cluster = gl_file.startcluster;\r
       remain = gl_file.filesize;\r
 \r
@@ -324,7 +364,6 @@ static unsigned char _f_fseek ( long offset )
           break;\r
         }\r
 \r
-        gl_file.prevcluster = gl_file.pos.cluster;\r
         gl_file.pos.cluster = cluster;\r
       }\r
 \r
@@ -351,6 +390,10 @@ static unsigned char _f_fseek ( long offset )
         gl_file.relpos = (unsigned short)offset;\r
       }\r
     }\r
+    else\r
+    {\r
+      ret = _f_extend( offset );\r
+    }\r
   }\r
 \r
   return ret;\r
@@ -450,7 +493,7 @@ F_FILE * fn_open ( const char * filename, const char * mode )
     return 0;\r
   }\r
 \r
-  psp_memset( &gl_file, 0, 21 );\r
+  psp_memset( &gl_file, 0, sizeof( F_FILE ) );\r
 \r
   if ( !_f_findpath( &fsname, &gl_file.dirpos ) )\r
   {\r
@@ -603,27 +646,6 @@ F_FILE * fn_open ( const char * filename, const char * mode )
       return 0;        /*invalid mode*/\r
   } /* switch */\r
 \r
-  if ( ( m_mode != F_FILE_RD ) && ( gl_file.startcluster == 0 ) )\r
-  {\r
-    gl_volume.fatsector = (unsigned long)-1;\r
-    if ( _f_alloccluster( &( gl_file.startcluster ) ) )\r
-    {\r
-      return 0;\r
-    }\r
-\r
-    _f_clustertopos( gl_file.startcluster, &gl_file.pos );\r
-    if ( _f_setclustervalue( gl_file.startcluster, F_CLUSTER_LAST ) )\r
-    {\r
-      return 0;\r
-    }\r
-\r
-    if ( _f_writefatsector() )\r
-    {\r
-      return 0;\r
-    }\r
-  }\r
-\r
-\r
   gl_file.mode = m_mode; /* lock it */\r
   return (F_FILE *)1;\r
 } /* fn_open */\r
@@ -965,6 +987,11 @@ long fn_write ( const void * buf, long size, long _size_st, F_FILE * f )
   _size_st = retsize;\r
   retsize = 0;\r
 \r
+  if ( size == 0 )\r
+  {\r
+    return 0;\r
+  }\r
+\r
   if ( _f_getvolume() )\r
   {\r
     return 0;                     /*can't write*/\r
@@ -979,10 +1006,21 @@ long fn_write ( const void * buf, long size, long _size_st, F_FILE * f )
     }\r
   }\r
 \r
-  if ( _f_getcurrsector() )\r
+  if ( gl_file.startcluster == 0 )\r
   {\r
-    gl_file.mode = F_FILE_CLOSE;\r
-    return 0;\r
+    if ( _f_stepnextsector() )\r
+    {\r
+      gl_file.mode = F_FILE_CLOSE;\r
+      return 0;\r
+    }\r
+  }\r
+  else\r
+  {\r
+    if ( _f_getcurrsector() )\r
+    {\r
+      gl_file.mode = F_FILE_CLOSE;\r
+      return 0;\r
+    }\r
   }\r
 \r
   for( ; ; )\r
@@ -993,7 +1031,7 @@ long fn_write ( const void * buf, long size, long _size_st, F_FILE * f )
     {     /*now full*/\r
       if ( gl_file.modified )\r
       {\r
-        if ( _f_emptywritebuffer() )\r
+        if ( _f_writeglsector( gl_file.pos.sector ) )\r
         {\r
           gl_file.mode = F_FILE_CLOSE;\r
           if ( _f_updatefileentry( 0 ) == 0 )\r
@@ -1005,10 +1043,21 @@ long fn_write ( const void * buf, long size, long _size_st, F_FILE * f )
             return 0;\r
           }\r
         }\r
+\r
+        gl_file.modified = 0;\r
       }\r
-      else\r
+\r
+      if ( _f_stepnextsector() )\r
       {\r
-        gl_file.pos.sector++;       /*goto next*/\r
+        gl_file.mode = F_FILE_CLOSE;\r
+        if ( _f_updatefileentry( 0 ) == 0 )\r
+        {\r
+          return retsize;\r
+        }\r
+        else\r
+        {\r
+          return 0;\r
+        }\r
       }\r
 \r
       gl_file.abspos += gl_file.relpos;\r