Repository: incubator-mynewt-core
Updated Branches:
  refs/heads/develop d886fa15d -> e7fc231a6


boot - Don't read full sector layout upfront.

Previously, the boot loader would read the properties of all image
sectors at startup.  This was a problem for the split image setup
because it required the allocation of a massive chunk of memory to hold
the sector info (at least 4kB).

Now, the boot loader retrieves sector information from the HAL on an
as-needed basis, eliminating the need for the upfront allocation.


Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/repo
Commit: 
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/commit/e7fc231a
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/tree/e7fc231a
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/diff/e7fc231a

Branch: refs/heads/develop
Commit: e7fc231a687dabf70b53be004c18289b40fd876b
Parents: 0dd24d4
Author: Christopher Collins <[email protected]>
Authored: Mon Jan 16 12:29:31 2017 -0800
Committer: Christopher Collins <[email protected]>
Committed: Mon Jan 16 14:21:46 2017 -0800

----------------------------------------------------------------------
 boot/bootutil/src/loader.c                      | 164 +++++++++++--------
 sys/config/src/config_init.c                    |  30 ++--
 sys/flash_map/include/flash_map/flash_map.h     |  13 +-
 sys/flash_map/src/flash_map.c                   |  45 ++++-
 .../test/src/testcases/flash_map_test_case_1.c  |   2 +-
 .../test/src/testcases/flash_map_test_case_2.c  |   2 +-
 6 files changed, 161 insertions(+), 95 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e7fc231a/boot/bootutil/src/loader.c
----------------------------------------------------------------------
diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c
index f473c90..e219ff7 100644
--- a/boot/bootutil/src/loader.c
+++ b/boot/bootutil/src/loader.c
@@ -40,15 +40,16 @@
 /** Number of image slots in flash; currently limited to two. */
 #define BOOT_NUM_SLOTS              2
 
-static struct {
-    struct {
-        struct image_header hdr;
-        struct flash_area *sectors;
-        int num_sectors;
-    } imgs[BOOT_NUM_SLOTS];
-
-    struct flash_area scratch_sector;
+struct boot_slot {
+    struct image_header hdr;
+    struct flash_area area;
+    int first_sector_idx;
+    int num_sectors;
+};
 
+static struct {
+    struct boot_slot slots[BOOT_NUM_SLOTS];
+    struct flash_area scratch_area;
     uint8_t write_sz;
 } boot_data;
 
@@ -216,6 +217,21 @@ boot_previous_swap_type(void)
     return BOOT_SWAP_TYPE_REVERT;
 }
 
+static void
+boot_read_sector(int slot_idx, int sector_idx, struct flash_area *out_sect)
+{
+    const struct boot_slot *slot;
+    int rc;
+
+    assert(slot_idx >= 0 && slot_idx < BOOT_NUM_SLOTS);
+    slot = boot_data.slots + slot_idx;
+
+    rc = flash_read_sector(slot->area.fa_device_id,
+                           slot->first_sector_idx + sector_idx,
+                           out_sect);
+    assert(rc == 0);
+}
+
 static int
 boot_read_image_header(int slot, struct image_header *out_hdr)
 {
@@ -250,7 +266,7 @@ boot_read_image_headers(void)
     int i;
 
     for (i = 0; i < BOOT_NUM_SLOTS; i++) {
-        rc = boot_read_image_header(i, &boot_data.imgs[i].hdr);
+        rc = boot_read_image_header(i, &boot_data.slots[i].hdr);
         if (rc != 0) {
             /* If at least one header was read successfully, then the boot
              * loader can attempt a boot.  Failure to read any headers is a
@@ -277,8 +293,8 @@ boot_write_sz(void)
      * on what the minimum write size is for scratch area, active image slot.
      * We need to use the bigger of those 2 values.
      */
-    elem_sz = hal_flash_align(boot_data.imgs[0].sectors[0].fa_device_id);
-    align = hal_flash_align(boot_data.scratch_sector.fa_device_id);
+    elem_sz = hal_flash_align(boot_data.slots[0].area.fa_device_id);
+    align = hal_flash_align(boot_data.scratch_area.fa_device_id);
     if (align > elem_sz) {
         elem_sz = align;
     }
@@ -289,18 +305,19 @@ boot_write_sz(void)
 static int
 boot_slots_compatible(void)
 {
-    const struct flash_area *sector0;
-    const struct flash_area *sector1;
+    struct flash_area sector0;
+    struct flash_area sector1;
     int i;
 
     /* Ensure both image slots have identical sector layouts. */
-    if (boot_data.imgs[0].num_sectors != boot_data.imgs[1].num_sectors) {
+    if (boot_data.slots[0].num_sectors != boot_data.slots[1].num_sectors) {
         return 0;
     }
-    for (i = 0; i < boot_data.imgs[0].num_sectors; i++) {
-        sector0 = boot_data.imgs[0].sectors + i;
-        sector1 = boot_data.imgs[1].sectors + i;
-        if (sector0->fa_size != sector1->fa_size) {
+    for (i = 0; i < boot_data.slots[0].num_sectors; i++) {
+        boot_read_sector(0, i, &sector0);
+        boot_read_sector(1, i, &sector1);
+
+        if (sector0.fa_size != sector1.fa_size) {
             return 0;
         }
     }
@@ -318,32 +335,59 @@ static int
 boot_read_sectors(void)
 {
     const struct flash_area *scratch;
-    int num_sectors_slot0;
-    int num_sectors_slot1;
+    const struct flash_area *slot0;
+    const struct flash_area *slot1;
     int rc;
 
-    num_sectors_slot0 = BOOT_MAX_IMG_SECTORS;
-    rc = flash_area_to_sectors(FLASH_AREA_IMAGE_0, &num_sectors_slot0,
-                               boot_data.imgs[0].sectors);
+    /*** Slot 0. */
+
+    rc = flash_area_open(FLASH_AREA_IMAGE_0, &slot0);
     if (rc != 0) {
         return BOOT_EFLASH;
     }
-    boot_data.imgs[0].num_sectors = num_sectors_slot0;
 
-    num_sectors_slot1 = BOOT_MAX_IMG_SECTORS;
-    rc = flash_area_to_sectors(FLASH_AREA_IMAGE_1, &num_sectors_slot1,
-                               boot_data.imgs[1].sectors);
+    /* Remember flash area properties. */
+    boot_data.slots[0].area = *slot0;
+
+    /* Determine sector count. */
+    rc = flash_area_to_sectors(FLASH_AREA_IMAGE_0,
+                               &boot_data.slots[0].first_sector_idx,
+                               &boot_data.slots[0].num_sectors,
+                               NULL);
     if (rc != 0) {
         return BOOT_EFLASH;
     }
-    boot_data.imgs[1].num_sectors = num_sectors_slot1;
+
+    /*** Slot 1. */
+
+    rc = flash_area_open(FLASH_AREA_IMAGE_1, &slot1);
+    if (rc != 0) {
+        return BOOT_EFLASH;
+    }
+
+    /* Remember flash area properties. */
+    boot_data.slots[1].area = *slot1;
+
+    /* Determine sector count. */
+    rc = flash_area_to_sectors(FLASH_AREA_IMAGE_1,
+                               &boot_data.slots[1].first_sector_idx,
+                               &boot_data.slots[1].num_sectors,
+                               NULL);
+    if (rc != 0) {
+        return BOOT_EFLASH;
+    }
+
+    /*** Scratch. */
 
     rc = flash_area_open(FLASH_AREA_IMAGE_SCRATCH, &scratch);
     if (rc != 0) {
         return BOOT_EFLASH;
     }
-    boot_data.scratch_sector = *scratch;
 
+    /* Remember flash area properties. */
+    boot_data.scratch_area = *scratch;
+
+    /* Determine flash hardware's minimum write size. */
     boot_data.write_sz = boot_write_sz();
 
     return 0;
@@ -448,7 +492,7 @@ boot_read_status(struct boot_status *bs)
 }
 
 /**
- * Writes the supplied boot status to the flash file system.  The boot status
+ * Writes the supplied boot status to the boot vector.  The boot status
  * contains the current state of an in-progress image copy operation.
  *
  * @param bs                    The boot status to write.
@@ -549,8 +593,8 @@ boot_validate_slot1(void)
     const struct flash_area *fap;
     int rc;
     
-    if (boot_data.imgs[1].hdr.ih_magic == 0xffffffff ||
-        boot_data.imgs[1].hdr.ih_flags & IMAGE_F_NON_BOOTABLE) {
+    if (boot_data.slots[1].hdr.ih_magic == 0xffffffff ||
+        boot_data.slots[1].hdr.ih_flags & IMAGE_F_NON_BOOTABLE) {
 
         /* No bootable image in slot 1; continue booting from slot 0. */
         return -1;
@@ -564,8 +608,8 @@ boot_validate_slot1(void)
         return BOOT_EFLASH;
     }
 
-    if (boot_data.imgs[1].hdr.ih_magic != IMAGE_MAGIC ||
-        boot_image_check(&boot_data.imgs[1].hdr, fap) != 0) {
+    if (boot_data.slots[1].hdr.ih_magic != IMAGE_MAGIC ||
+        boot_image_check(&boot_data.slots[1].hdr, fap) != 0) {
 
         /* Image in slot 1 is invalid.  Erase the image and continue booting
          * from slot 0.
@@ -625,6 +669,7 @@ boot_validated_swap_type(void)
 static uint32_t
 boot_copy_sz(int last_sector_idx, int *out_first_sector_idx)
 {
+    struct flash_area sector;
     uint32_t new_sz;
     uint32_t sz;
     int i;
@@ -632,8 +677,9 @@ boot_copy_sz(int last_sector_idx, int *out_first_sector_idx)
     sz = 0;
 
     for (i = last_sector_idx; i >= 0; i--) {
-        new_sz = sz + boot_data.imgs[0].sectors[i].fa_size;
-        if (new_sz > boot_data.scratch_sector.fa_size) {
+        boot_read_sector(0, i, &sector);
+        new_sz = sz + sector.fa_size;
+        if (new_sz > boot_data.scratch_area.fa_size) {
             break;
         }
         sz = new_sz;
@@ -768,13 +814,15 @@ done:
 static int
 boot_swap_sectors(int idx, uint32_t sz, struct boot_status *bs)
 {
+    struct flash_area sector;
     uint32_t copy_sz;
     uint32_t img_off;
     int rc;
 
+    boot_read_sector(0, idx, &sector);
+
     /* Calculate offset from start of image area. */
-    img_off = boot_data.imgs[0].sectors[idx].fa_off -
-              boot_data.imgs[0].sectors[0].fa_off;
+    img_off = sector.fa_off - boot_data.slots[0].area.fa_off;
 
     if (bs->state == 0) {
         rc = boot_erase_sector(FLASH_AREA_IMAGE_SCRATCH, 0, sz);
@@ -798,9 +846,7 @@ boot_swap_sectors(int idx, uint32_t sz, struct boot_status 
*bs)
         }
 
         copy_sz = sz;
-        if (boot_data.imgs[0].sectors[idx].fa_off + sz >=
-            boot_data.imgs[1].sectors[0].fa_off) {
-
+        if (img_off + sz >= boot_data.slots[0].area.fa_size) {
             /* This is the end of the area.  Don't copy the image state into
              * slot 1.
              */
@@ -857,7 +903,7 @@ boot_copy_image(struct boot_status *bs)
     int swap_idx;
 
     swap_idx = 0;
-    last_sector_idx = boot_data.imgs[0].num_sectors - 1;
+    last_sector_idx = boot_data.slots[0].num_sectors - 1;
     while (last_sector_idx >= 0) {
         sz = boot_copy_sz(last_sector_idx, &first_sector_idx);
         if (swap_idx >= bs->idx) {
@@ -1002,16 +1048,6 @@ boot_go(struct boot_rsp *rsp)
     int slot;
     int rc;
 
-    /* The array of slot sectors are defined here (as opposed to file scope) so
-     * that they don't get allocated for non-boot-loader apps.  This is
-     * necessary because the gcc option "-fdata-sections" doesn't seem to have
-     * any effect in older gcc versions (e.g., 4.8.4).
-     */
-    static struct flash_area slot0_sectors[BOOT_MAX_IMG_SECTORS];
-    static struct flash_area slot1_sectors[BOOT_MAX_IMG_SECTORS];
-    boot_data.imgs[0].sectors = slot0_sectors;
-    boot_data.imgs[1].sectors = slot1_sectors;
-
     /* Determine the sector layout of the image slots and scratch area. */
     rc = boot_read_sectors();
     if (rc != 0) {
@@ -1068,9 +1104,9 @@ boot_go(struct boot_rsp *rsp)
     }
 
     /* Always boot from the primary slot. */
-    rsp->br_flash_id = boot_data.imgs[0].sectors[0].fa_device_id;
-    rsp->br_image_addr = boot_data.imgs[0].sectors[0].fa_off;
-    rsp->br_hdr = &boot_data.imgs[slot].hdr;
+    rsp->br_flash_id = boot_data.slots[0].area.fa_device_id;
+    rsp->br_image_addr = boot_data.slots[0].area.fa_off;
+    rsp->br_hdr = &boot_data.slots[slot].hdr;
 
     return 0;
 }
@@ -1080,7 +1116,6 @@ split_go(int loader_slot, int split_slot, void **entry)
 {
     const struct flash_area *loader_fap;
     const struct flash_area *app_fap;
-    struct flash_area *sectors;
     uintptr_t entry_val;
     int loader_flash_id;
     int app_flash_id;
@@ -1089,14 +1124,6 @@ split_go(int loader_slot, int split_slot, void **entry)
     app_fap = NULL;
     loader_fap = NULL;
 
-    sectors = malloc(BOOT_MAX_IMG_SECTORS * 2 * sizeof *sectors);
-    if (sectors == NULL) {
-        rc = SPLIT_GO_ERR;
-        goto done;
-    }
-    boot_data.imgs[0].sectors = sectors + 0;
-    boot_data.imgs[1].sectors = sectors + BOOT_MAX_IMG_SECTORS;
-
     /* Determine the sector layout of the image slots and scratch area. */
     rc = boot_read_sectors();
     if (rc != 0) {
@@ -1127,22 +1154,21 @@ split_go(int loader_slot, int split_slot, void **entry)
      * bootable or non-bootable image.  Just validate that the image check
      * passes which is distinct from the normal check.
      */
-    rc = split_image_check(&boot_data.imgs[split_slot].hdr,
+    rc = split_image_check(&boot_data.slots[split_slot].hdr,
                            app_fap,
-                           &boot_data.imgs[loader_slot].hdr,
+                           &boot_data.slots[loader_slot].hdr,
                            loader_fap);
     if (rc != 0) {
         rc = SPLIT_GO_NON_MATCHING;
         goto done;
     }
 
-    entry_val = boot_data.imgs[split_slot].sectors[0].fa_off +
-                boot_data.imgs[split_slot].hdr.ih_hdr_size;
+    entry_val = boot_data.slots[split_slot].area.fa_off +
+                boot_data.slots[split_slot].hdr.ih_hdr_size;
     *entry = (void *) entry_val;
     rc = SPLIT_GO_OK;
 
 done:
-    free(sectors);
     flash_area_close(app_fap);
     flash_area_close(loader_fap);
     return rc;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e7fc231a/sys/config/src/config_init.c
----------------------------------------------------------------------
diff --git a/sys/config/src/config_init.c b/sys/config/src/config_init.c
index 53a5f25..6b429bd 100644
--- a/sys/config/src/config_init.c
+++ b/sys/config/src/config_init.c
@@ -51,40 +51,42 @@ config_init_fs(void)
 #include "fcb/fcb.h"
 #include "config/config_fcb.h"
 
-static struct flash_area conf_fcb_area[NFFS_AREA_MAX + 1];
+static struct flash_area conf_fcb_sectors[NFFS_AREA_MAX + 1];
 
 static struct conf_fcb config_init_conf_fcb = {
     .cf_fcb.f_magic = MYNEWT_VAL(CONFIG_FCB_MAGIC),
-    .cf_fcb.f_sectors = conf_fcb_area,
+    .cf_fcb.f_sectors = conf_fcb_sectors,
 };
 
 static void
 config_init_fcb(void)
 {
+    const struct flash_area *fap;
     int cnt;
     int rc;
 
-    rc = flash_area_to_sectors(MYNEWT_VAL(CONFIG_FCB_FLASH_AREA), &cnt, NULL);
+    rc = flash_area_to_sectors(MYNEWT_VAL(CONFIG_FCB_FLASH_AREA), NULL,
+                               &cnt, NULL);
     SYSINIT_PANIC_ASSERT(rc == 0);
     SYSINIT_PANIC_ASSERT(
-        cnt <= sizeof(conf_fcb_area) / sizeof(conf_fcb_area[0]));
+        cnt <= sizeof(conf_fcb_sectors) / sizeof(conf_fcb_sectors[0]));
     flash_area_to_sectors(
-        MYNEWT_VAL(CONFIG_FCB_FLASH_AREA), &cnt, conf_fcb_area);
+        MYNEWT_VAL(CONFIG_FCB_FLASH_AREA), NULL, &cnt, conf_fcb_sectors);
 
     config_init_conf_fcb.cf_fcb.f_sector_cnt = cnt;
 
+    rc = flash_area_open(MYNEWT_VAL(CONFIG_FCB_FLASH_AREA), &fap);
+    SYSINIT_PANIC_ASSERT(rc == 0);
+
     rc = conf_fcb_src(&config_init_conf_fcb);
-    if (rc) {
-        for (cnt = 0;
-             cnt < config_init_conf_fcb.cf_fcb.f_sector_cnt;
-             cnt++) {
-
-            flash_area_erase(&conf_fcb_area[cnt], 0,
-                             conf_fcb_area[cnt].fa_size);
-        }
+    if (rc != 0) {
+        rc = flash_area_erase(fap, 0, fap->fa_size);
+        SYSINIT_PANIC_ASSERT(rc == 0);
+
         rc = conf_fcb_src(&config_init_conf_fcb);
+        SYSINIT_PANIC_ASSERT(rc == 0);
     }
-    SYSINIT_PANIC_ASSERT(rc == 0);
+
     rc = conf_fcb_dst(&config_init_conf_fcb);
     SYSINIT_PANIC_ASSERT(rc == 0);
 }

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e7fc231a/sys/flash_map/include/flash_map/flash_map.h
----------------------------------------------------------------------
diff --git a/sys/flash_map/include/flash_map/flash_map.h 
b/sys/flash_map/include/flash_map/flash_map.h
index c0c9489..00401cd 100644
--- a/sys/flash_map/include/flash_map/flash_map.h
+++ b/sys/flash_map/include/flash_map/flash_map.h
@@ -43,6 +43,11 @@ extern "C" {
  */
 #include <inttypes.h>
 
+/**
+ * Represents a named region of flash.
+ *
+ * NOTE: Also used to represent an individual sector.
+ */
 struct flash_area {
     uint8_t fa_id;
     uint8_t fa_device_id;
@@ -84,7 +89,13 @@ uint8_t flash_area_align(const struct flash_area *);
 /*
  * Given flash map index, return info about sectors within the area.
  */
-int flash_area_to_sectors(int idx, int *cnt, struct flash_area *ret);
+int flash_area_to_sectors(int id,
+                          int *out_first_sector_idx,
+                          int *out_num_sectors,
+                          struct flash_area *out_sectors);
+
+int flash_read_sector(int area_id, int sector_idx,
+                      struct flash_area *out_sect);
 
 int flash_area_id_from_image_slot(int slot);
 int flash_area_id_to_image_slot(int area_id);

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e7fc231a/sys/flash_map/src/flash_map.c
----------------------------------------------------------------------
diff --git a/sys/flash_map/src/flash_map.c b/sys/flash_map/src/flash_map.c
index b652de0..6ccc877 100644
--- a/sys/flash_map/src/flash_map.c
+++ b/sys/flash_map/src/flash_map.c
@@ -62,12 +62,34 @@ flash_area_close(const struct flash_area *fa)
 }
 
 int
-flash_area_to_sectors(int id, int *cnt, struct flash_area *ret)
+flash_read_sector(int device_id, int sector_idx, struct flash_area *out_sect)
+{
+    const struct hal_flash *hf;
+    uint32_t start;
+    uint32_t size;
+
+    hf = hal_bsp_flash_dev(device_id);
+    hf->hf_itf->hff_sector_info(sector_idx, &start, &size);
+    if (out_sect != NULL) {
+        out_sect->fa_device_id = device_id;
+        out_sect->fa_off = start;
+        out_sect->fa_size = size;
+    }
+
+    return 0;
+}
+
+int
+flash_area_to_sectors(int id,
+                      int *out_first_sector_idx,
+                      int *out_num_sectors,
+                      struct flash_area *out_sectors)
 {
     const struct flash_area *fa;
     const struct hal_flash *hf;
     uint32_t start;
     uint32_t size;
+    int first;
     int rc;
     int i;
 
@@ -76,20 +98,25 @@ flash_area_to_sectors(int id, int *cnt, struct flash_area 
*ret)
         return rc;
     }
 
-    *cnt = 0;
+    first = 1;
+    *out_num_sectors = 0;
 
     hf = hal_bsp_flash_dev(fa->fa_device_id);
     for (i = 0; i < hf->hf_sector_cnt; i++) {
         hf->hf_itf->hff_sector_info(i, &start, &size);
         if (start >= fa->fa_off && start < fa->fa_off + fa->fa_size) {
-            if (ret) {
-                ret->fa_id = id;
-                ret->fa_device_id = fa->fa_device_id;
-                ret->fa_off = start;
-                ret->fa_size = size;
-                ret++;
+            if (first && out_first_sector_idx != NULL) {
+                *out_first_sector_idx = i;
+            }
+            if (out_sectors != NULL) {
+                out_sectors->fa_id = id;
+                out_sectors->fa_device_id = fa->fa_device_id;
+                out_sectors->fa_off = start;
+                out_sectors->fa_size = size;
+                out_sectors++;
             }
-            (*cnt)++;
+            first = 0;
+            (*out_num_sectors)++;
         }
     }
     return 0;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e7fc231a/sys/flash_map/test/src/testcases/flash_map_test_case_1.c
----------------------------------------------------------------------
diff --git a/sys/flash_map/test/src/testcases/flash_map_test_case_1.c 
b/sys/flash_map/test/src/testcases/flash_map_test_case_1.c
index b4a7f79..c797d62 100644
--- a/sys/flash_map/test/src/testcases/flash_map_test_case_1.c
+++ b/sys/flash_map/test/src/testcases/flash_map_test_case_1.c
@@ -46,7 +46,7 @@ TEST_CASE(flash_map_test_case_1)
         hf = hal_bsp_flash_dev(fa->fa_device_id);
         TEST_ASSERT_FATAL(hf != NULL, "hal_bsp_flash_dev");
 
-        rc = flash_area_to_sectors(i, &sect_cnt, fa_sectors);
+        rc = flash_area_to_sectors(i, NULL, &sect_cnt, fa_sectors);
         TEST_ASSERT_FATAL(rc == 0, "flash_area_to_sectors failed");
 
         end = fa->fa_off;

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/e7fc231a/sys/flash_map/test/src/testcases/flash_map_test_case_2.c
----------------------------------------------------------------------
diff --git a/sys/flash_map/test/src/testcases/flash_map_test_case_2.c 
b/sys/flash_map/test/src/testcases/flash_map_test_case_2.c
index 412c320..4adb545 100644
--- a/sys/flash_map/test/src/testcases/flash_map_test_case_2.c
+++ b/sys/flash_map/test/src/testcases/flash_map_test_case_2.c
@@ -40,7 +40,7 @@ TEST_CASE(flash_map_test_case_2)
     rc = flash_area_open(FLASH_AREA_IMAGE_0, &fa);
     TEST_ASSERT_FATAL(rc == 0, "flash_area_open() fail");
 
-    rc = flash_area_to_sectors(FLASH_AREA_IMAGE_0, &sec_cnt, fa_sectors);
+    rc = flash_area_to_sectors(FLASH_AREA_IMAGE_0, NULL, &sec_cnt, fa_sectors);
     TEST_ASSERT_FATAL(rc == 0, "flash_area_to_sectors failed");
 
     /*

Reply via email to