瀏覽代碼

Don't allocate flash to SPIFFS that is reserved by the system. (#3260)

Philip Gladstone 3 年之前
父節點
當前提交
ba611101e5
共有 3 個文件被更改,包括 78 次插入60 次删除
  1. 26 32
      app/modules/node.c
  2. 39 21
      app/user/user_main.c
  3. 13 7
      tools/nodemcu-partition.py

+ 26 - 32
app/modules/node.c

@@ -750,8 +750,9 @@ static void delete_partition(partition_item_t *p, int n) {
 #define IROM0_PARTITION  (SYSTEM_PARTITION_CUSTOMER_BEGIN + NODEMCU_IROM0TEXT_PARTITION)
 #define LFS_PARTITION    (SYSTEM_PARTITION_CUSTOMER_BEGIN + NODEMCU_LFS0_PARTITION)
 #define SPIFFS_PARTITION (SYSTEM_PARTITION_CUSTOMER_BEGIN + NODEMCU_SPIFFS0_PARTITION)
+#define SYSTEM_PARAMETER_SIZE  0x3000
 
-// Lua: node.setpartitiontable(pt_settings)
+// Lua: node.setpartitiontable(ptvals)
 static int node_setpartitiontable (lua_State *L) {
   partition_item_t *rcr_pt = NULL, *pt;
   uint32_t flash_size = flash_rom_get_size_byte();
@@ -760,6 +761,7 @@ static int node_setpartitiontable (lua_State *L) {
   uint32_t n = i / sizeof(partition_item_t);
   uint32_t param[max_pt] = {SKIP, SKIP, SKIP, SKIP};
 
+/* stack 1=ptvals, 2=pt_map, 3=key, 4=ptval[key], 5=pt_map[key] */ 
   luaL_argcheck(L, lua_istable(L, 1), 1, "must be table");
   lua_settop(L, 1);
   /* convert input table into 4 option array */
@@ -771,9 +773,8 @@ static int node_setpartitiontable (lua_State *L) {
     lua_pushvalue(L, 3);  /* dup key to index 5 */
     lua_rawget(L, 2);     /* lookup in pt_map */
     luaL_argcheck(L, !lua_isnil(L, -1), 1, "invalid partition setting");
-    param[lua_tointeger(L, 5)] = lua_tointeger(L, 4);
-    /* removes 'value'; keeps 'key' for next iteration */
-    lua_pop(L, 2);  /* discard value and lookup */
+    param[lua_tointeger(L, 5)] = lua_tounsigned(L, 4);
+    lua_pop(L, 2);  /* discard value and lookup; keeps 'key' for next iteration */
   }
  /*
   * Allocate a scratch Partition Table as userdata on the Lua stack, and copy the
@@ -793,43 +794,34 @@ static int node_setpartitiontable (lua_State *L) {
       n++;
 
     } else if (p->type == LFS_PARTITION) {
+      // update the LFS options if set
+      if (param[lfs_addr] != SKIP) 
+        p->addr = param[lfs_addr];
+      if (param[lfs_size] != SKIP) 
+        p->size = param[lfs_size];
       if (p[1].type != SPIFFS_PARTITION) {
         // if the SPIFFS partition is not following LFS then slot a blank one in
         insert_partition(p + 1, n-i-1, SPIFFS_PARTITION, 0);
         n++;
       }
-      // update the LFS options if set
-      if (param[lfs_addr] != SKIP) {
-        p->addr = param[lfs_addr];
-      }
-      if (param[lfs_size] != SKIP) {
-        p->size = param[lfs_size];
-      }
+
     } else if (p->type == SPIFFS_PARTITION) {
       // update the SPIFFS options if set
-      if (param[spiffs_addr] != SKIP) {
+      if (param[spiffs_size] != SKIP) {
+        p->size = param[spiffs_size];
+        p->addr = (param[spiffs_addr] != SKIP) ? param[spiffs_addr] :
+                    ((p->size <= flash_size - SYSTEM_PARAMETER_SIZE - 0x100000)
+                     ? 0x100000 : last);
+      } else if (param[spiffs_addr] != SKIP) {
         p->addr = param[spiffs_addr];
-        p->size = SKIP;
       }
+#if 0
       if (param[spiffs_size] != SKIP) {
         // BOTCH: - at the moment the firmware doesn't boot if the SPIFFS partition
         //          is deleted so the minimum SPIFFS size is 64Kb
         p->size = param[spiffs_size] > 0x10000 ? param[spiffs_size] : 0x10000;
       }
-      if (p->size == SKIP) {
-        if (p->addr < 0) {
-          // This allocate all the remaining flash to SPIFFS
-          p->addr = last;
-          p->size = flash_size - last;
-        } else {
-          p->size = flash_size - p->addr;
-        }
-      } else if (/* size is specified && */ p->addr == 0) {
-        // if the is addr not specified then start SPIFFS at 1Mb
-        // boundary if the size will fit otherwise make it consecutive
-        // to the previous partition.
-        p->addr = (p->size <= flash_size - 0x100000) ? 0x100000 : last;
-      }
+#endif
     }
 
     if (p->size == 0) {
@@ -842,14 +834,16 @@ static int node_setpartitiontable (lua_State *L) {
         p->size & (INTERNAL_FLASH_SECTOR_SIZE - 1) ||
         p->addr < last ||
         p->addr + p->size > flash_size) {
-        luaL_error(L, "value out of range");
+        luaL_error(L, "Partition value out of range");
       }
+      last = p->addr + p->size;
     }
   }
-//  for (i = 0; i < n; i ++)
-//    dbg_printf("Partition %d: %04x %06x %06x\n", i, pt[i].type, pt[i].addr, pt[i].size);
-    platform_rcr_write(PLATFORM_RCR_PT, pt, n*sizeof(partition_item_t));
-    while(1); // Trigger WDT; the new PT will be loaded on reboot
+  for (i = 0; i < n; i ++)
+    dbg_printf("Partition %d: %04x %06x %06x\n", i, pt[i].type, pt[i].addr, pt[i].size);
+
+  platform_rcr_write(PLATFORM_RCR_PT, pt, n*sizeof(partition_item_t));
+  while(1); // Trigger WDT; the new PT will be loaded on reboot
 
   return 0;
 }

+ 39 - 21
app/user/user_main.c

@@ -40,8 +40,8 @@ __asm__(
   "init_data_end:\n"
 );
 extern const char _irom0_text_start[], _irom0_text_end[], _flash_used_end[];
-#define IROM0_SIZE (_irom0_text_end - _irom0_text_start)
 
+#define IROM0_SIZE (_irom0_text_end - _irom0_text_start)
 
 #define PRE_INIT_TEXT_ATTR        __attribute__((section(".p3.pre_init")))
 #define IROM_PTABLE_ATTR          __attribute__((section(".irom0.ptable")))
@@ -60,9 +60,14 @@ extern const char _irom0_text_start[], _irom0_text_end[], _flash_used_end[];
 #define NODEMCU_PARTITION_LFS       PLATFORM_PARTITION(NODEMCU_LFS0_PARTITION)
 #define NODEMCU_PARTITION_SPIFFS    PLATFORM_PARTITION(NODEMCU_SPIFFS0_PARTITION)
 
+#define RF_CAL_SIZE            0x1000
+#define PHY_DATA_SIZE          0x1000
+#define SYSTEM_PARAMETER_SIZE  0x3000
+
 #define MAX_PARTITIONS 20
 #define WORDSIZE       sizeof(uint32_t)
 #define PTABLE_SIZE    7   /** THIS MUST BE MATCHED TO NO OF PT ENTRIES BELOW **/
+
 struct defaultpt {
   platform_rcr_t hdr;
   partition_item_t pt[PTABLE_SIZE+1]; // the +! is for the endmarker
@@ -78,12 +83,12 @@ static const struct defaultpt rompt IROM_PTABLE_ATTR USED_ATTR  = {
           .id  = PLATFORM_RCR_PT},
   .pt  = {
     { NODEMCU_PARTITION_EAGLEROM,         0x00000,     0x0B000},
-    { SYSTEM_PARTITION_RF_CAL,            0x0B000,      0x1000},
-    { SYSTEM_PARTITION_PHY_DATA,          0x0C000,      0x1000},
-    { SYSTEM_PARTITION_SYSTEM_PARAMETER,  0x0D000,      0x3000},
-    { NODEMCU_PARTITION_IROM0TEXT,        0x10000,      0x0000},
-    { NODEMCU_PARTITION_LFS,              0x0,          LUA_FLASH_STORE},
-    { NODEMCU_PARTITION_SPIFFS,           0x0,          SPIFFS_MAX_FILESYSTEM_SIZE},
+    { SYSTEM_PARTITION_RF_CAL,            0x0D000,     RF_CAL_SIZE},
+    { SYSTEM_PARTITION_PHY_DATA,          0x0F000,     PHY_DATA_SIZE},
+    { NODEMCU_PARTITION_IROM0TEXT,        0x10000,     0x0000},
+    { NODEMCU_PARTITION_LFS,              0x0,         LUA_FLASH_STORE},
+    { NODEMCU_PARTITION_SPIFFS,           0x0,         SPIFFS_MAX_FILESYSTEM_SIZE},
+    { SYSTEM_PARTITION_SYSTEM_PARAMETER,  0x0,         SYSTEM_PARAMETER_SIZE},
     {0,(uint32_t) &_irom0_text_end,0}
   }
 };
@@ -161,7 +166,6 @@ void user_pre_init(void) {
     }
 
     // Now register the partition and return
-// for (i=0;i<n;i++) os_printf("P%d: %3d %06x %06x\n", i, pt[i].type, pt[i].addr, pt[i].size);
     if( fs_size_code > 1 && system_partition_table_regist(pt, n, fs_size_code)) {
         return;
     }
@@ -230,26 +234,41 @@ static uint32_t first_time_setup(partition_item_t *pt, uint32_t n, uint32_t flas
                 p->addr = last;
             break;
 
+         /*
+          * Set up the SPIFFS partition based on some sensible defaults:
+          *    size == 0 mean no SPIFFS partition.
+          *    size == ~0 means use all of the available flash for SPIFFS (resp the addr if set).
+          *    if size > 0 then float the default boundary to 1M if the SPIFFS will fit.
+          */
           case NODEMCU_PARTITION_SPIFFS:
-            if (p->size == ~0x0 && p->addr == 0) {
-                // This allocate all the remaining flash to SPIFFS
-                p->addr = last;
-                p->size = flash_size - last;
-            } else if (p->size == ~0x0) {
-                p->size = flash_size - p->addr;
-           }  else if (p->addr == 0) {
-                // if the is addr not specified then start SPIFFS at 1Mb
-                // boundary if the size will fit otherwise make it consecutive
-                // to the previous partition.
-                p->addr = (p->size <= flash_size - 0x100000) ? 0x100000 : last;
+            if (p->size == ~0x0) {         /* Maximum SPIFFS partition */               
+                if (p->addr == 0)
+                    p->addr = last;
+                p->size = flash_size - SYSTEM_PARAMETER_SIZE - last;
+            } else if (p->size > 0x0) {    /* Explicit SPIFFS size */
+                if (p->addr < last)   // SPIFFS can't overlap the previous region; 
+                    p->addr = 0; 
+                if (p->addr == 0)
+                    p->addr = (p->size <= flash_size - SYSTEM_PARAMETER_SIZE - 0x100000) ? 
+                              0x100000 : last;
             }
+            /* else p->size == 0              No SPIFFS partition */
+            break;
+
+          case SYSTEM_PARTITION_SYSTEM_PARAMETER:
+            p->addr = flash_size - SYSTEM_PARAMETER_SIZE;
+            p->size = SYSTEM_PARAMETER_SIZE;
         }
 
         if (p->size == 0) {
             // Delete 0-sized partitions as the SDK barfs on these
             newn--;
         } else {
-            // Do consistency tests on the partition
+           /*
+            * Do consistency tests on the partition.  The address and size must 
+            * be flash sector aligned.  Partitions can't overlap, and the last
+            * patition must fit within the flash size.
+            */
             if (p->addr & (INTERNAL_FLASH_SECTOR_SIZE - 1) ||
                 p->size & (INTERNAL_FLASH_SECTOR_SIZE - 1) ||
                 p->addr < last ||
@@ -259,7 +278,6 @@ static uint32_t first_time_setup(partition_item_t *pt, uint32_t n, uint32_t flas
             }
             if (j < i)   // shift the partition down if we have any deleted slots
                 pt[j] = *p;
-//os_printf("Partition %d: %04x %06x %06x\n", j, p->type, p->addr, p->size);
             j++;
             last = p->addr + p->size;
         }

+ 13 - 7
tools/nodemcu-partition.py

@@ -57,9 +57,10 @@ PARTITION_TYPE  = {
      106: 'SPIFFS0',
      107: 'SPIFFS1'}
 
-IROM0TEXT = 102
-LFS       = 103
-SPIFFS    = 106
+SYSTEM_PARAMETER = 6
+IROM0TEXT        = 102
+LFS              = 103
+SPIFFS           = 106
 
 MAX_PT_SIZE = 20*3
 FLASH_SIG          = 0xfafaa150
@@ -145,13 +146,15 @@ def load_PT(data, args):
     # and SPIFFS is the last partition.  We will need to revisit these algos if
     # we adopt a more flexible partiton allocation policy.  *** BOTCH WARNING ***
 
-    for i in range (0, len(PTrec), 3):
+    i = 0
+    while i < len(PTrec):
         if PTrec[i] == IROM0TEXT and args.ls is not None and \
             (len(PTrec) == i+3  or PTrec[i+3] != LFS):
             PTrec[i+3:i+3] = [LFS, 0, 0]
-            break
-    if PTrec[-3] != SPIFFS:
-        PTrec.extend([SPIFFS, 0, 0])
+        i += 3
+        
+    if PTrec[-6] != SPIFFS:
+        PTrec[-6:-6] = [SPIFFS, PTrec[-5] + PTrec[-4], 0x1000]
 
     lastEnd, newPT, map = 0,[], dict()
     print "  Partition          Start   Size \n  ------------------ ------ ------"
@@ -208,6 +211,9 @@ def load_PT(data, args):
             if Psize > 0:
                 map['SPIFFS'] = {"addr" : Paddr, "size" : Psize}
 
+        elif Ptype == SYSTEM_PARAMETER and Paddr == 0:
+            Paddr = flash_size - Psize
+ 
         if Psize > 0:
             Pname = PARTITION_TYPE[Ptype] if Ptype in PARTITION_TYPE \
                                           else ("Type %d" % Ptype)