2727
2828#include " mcuboot_config/mcuboot_logging.h"
2929
30+ #include " bootutil_priv.h"
31+
3032#define FLASH_DEVICE_INTERNAL_FLASH 0
3133#define FLASH_AREAS 3
3234
@@ -36,15 +38,15 @@ mbed::BlockDevice* mcuboot_secondary_bd = get_secondary_bd();
3638/* * Internal application block device */
3739static FlashIAPBlockDevice mcuboot_primary_bd (MCUBOOT_PRIMARY_SLOT_START_ADDR, MCUBOOT_SLOT_SIZE);
3840
39- #ifndef MCUBOOT_OVERWRITE_ONLY
41+ #if MCUBOOT_SWAP_USING_SCRATCH
4042/* * Scratch space is at the end of internal flash, after the main application */
4143static FlashIAPBlockDevice mcuboot_scratch_bd (MCUBOOT_SCRATCH_START_ADDR, MCUBOOT_SCRATCH_SIZE);
4244#endif
4345
4446static mbed::BlockDevice* flash_map_bd[FLASH_AREAS] = {
4547 (mbed::BlockDevice*) &mcuboot_primary_bd, /* * Primary (loadable) image area */
4648 mcuboot_secondary_bd, /* * Secondary (update candidate) image area */
47- #ifndef MCUBOOT_OVERWRITE_ONLY
49+ #if MCUBOOT_SWAP_USING_SCRATCH
4850 (mbed::BlockDevice*) &mcuboot_scratch_bd /* * Scratch space for swapping images */
4951#else
5052 nullptr
@@ -53,6 +55,8 @@ static mbed::BlockDevice* flash_map_bd[FLASH_AREAS] = {
5355
5456static struct flash_area flash_areas[FLASH_AREAS];
5557
58+ static unsigned int open_count[FLASH_AREAS] = {0 };
59+
5660int flash_area_open (uint8_t id, const struct flash_area ** fapp) {
5761
5862 *fapp = &flash_areas[id];
@@ -64,10 +68,13 @@ int flash_area_open(uint8_t id, const struct flash_area** fapp) {
6468 fap->fa_off = MCUBOOT_PRIMARY_SLOT_START_ADDR;
6569 break ;
6670 case SECONDARY_ID:
67- // The offset of the secondary slot is not currently used.
71+ #if MCUBOOT_DIRECT_XIP
72+ fap->fa_off = MBED_CONF_MCUBOOT_XIP_SECONDARY_SLOT_ADDRESS;
73+ #else
6874 fap->fa_off = 0 ;
75+ #endif
6976 break ;
70- #ifndef MCUBOOT_OVERWRITE_ONLY
77+ #if MCUBOOT_SWAP_USING_SCRATCH
7178 case SCRATCH_ID:
7279 fap->fa_off = MCUBOOT_SCRATCH_START_ADDR;
7380 break ;
@@ -77,17 +84,40 @@ int flash_area_open(uint8_t id, const struct flash_area** fapp) {
7784 return -1 ;
7885 }
7986
87+ open_count[id]++;
88+ MCUBOOT_LOG_DBG (" flash area %d open count: %d (+)" , id, open_count[id]);
89+
8090 fap->fa_id = id;
8191 fap->fa_device_id = 0 ; // not relevant
8292
8393 mbed::BlockDevice* bd = flash_map_bd[id];
8494 fap->fa_size = (uint32_t ) bd->size ();
85- return bd->init ();
95+
96+ /* Only initialize if this isn't a nested call to open the flash area */
97+ if (open_count[id] == 1 ) {
98+ MCUBOOT_LOG_DBG (" initializing flash area %d..." , id);
99+ return bd->init ();
100+ } else {
101+ return 0 ;
102+ }
86103}
87104
88105void flash_area_close (const struct flash_area * fap) {
89- mbed::BlockDevice* bd = flash_map_bd[fap->fa_id ];
90- bd->deinit ();
106+ uint8_t id = fap->fa_id ;
107+ /* No need to close an unopened flash area, avoid an overflow of the counter */
108+ if (!open_count[id]) {
109+ return ;
110+ }
111+
112+ open_count[id]--;
113+ MCUBOOT_LOG_DBG (" flash area %d open count: %d (-)" , id, open_count[id]);
114+ if (!open_count[id]) {
115+ /* mcuboot is not currently consistent in opening/closing flash areas only once at a time
116+ * so only deinitialize the BlockDevice if all callers have closed the flash area. */
117+ MCUBOOT_LOG_DBG (" deinitializing flash area block device %d..." , id);
118+ mbed::BlockDevice* bd = flash_map_bd[id];
119+ bd->deinit ();
120+ }
91121}
92122
93123/*
@@ -96,8 +126,8 @@ void flash_area_close(const struct flash_area* fap) {
96126int flash_area_read (const struct flash_area * fap, uint32_t off, void * dst, uint32_t len) {
97127 mbed::BlockDevice* bd = flash_map_bd[fap->fa_id ];
98128
99- // Note: The address must be aligned to bd->get_read_size(). If MCUBOOT_READ_GRANULARITY
100- // is defined, the length does not need to be aligned.
129+ /* Note: The address must be aligned to bd->get_read_size(). If MCUBOOT_READ_GRANULARITY
130+ is defined, the length does not need to be aligned. */
101131#ifdef MCUBOOT_READ_GRANULARITY
102132 uint32_t read_size = bd->get_read_size ();
103133 if (read_size == 0 ) {
@@ -115,13 +145,15 @@ int flash_area_read(const struct flash_area* fap, uint32_t off, void* dst, uint3
115145 if (len != 0 ) {
116146#endif
117147 if (!bd->is_valid_read (off, len)) {
118- MCUBOOT_LOG_ERR (" Invalid read: fa_id %d offset 0x%x len 0x%x" , fap->fa_id , off, len);
148+ MCUBOOT_LOG_ERR (" Invalid read: fa_id %d offset 0x%x len 0x%x" , fap->fa_id ,
149+ (unsigned int ) off, (unsigned int ) len);
119150 return -1 ;
120151 }
121152 else {
122153 int ret = bd->read (dst, off, len);
123154 if (ret != 0 ) {
124- MCUBOOT_LOG_ERR (" Read failed: fa_id %d offset 0x%x len 0x%x" , fap->fa_id , off, len);
155+ MCUBOOT_LOG_ERR (" Read failed: fa_id %d offset 0x%x len 0x%x" , fap->fa_id ,
156+ (unsigned int ) off, (unsigned int ) len);
125157 return ret;
126158 }
127159 }
@@ -130,7 +162,8 @@ int flash_area_read(const struct flash_area* fap, uint32_t off, void* dst, uint3
130162
131163 if (remainder) {
132164 if (!bd->is_valid_read (off + len, read_size)) {
133- MCUBOOT_LOG_ERR (" Invalid read: fa_id %d offset 0x%x len 0x%x" , fap->fa_id , off + len, read_size);
165+ MCUBOOT_LOG_ERR (" Invalid read: fa_id %d offset 0x%x len 0x%x" , fap->fa_id ,
166+ (unsigned int ) (off + len), (unsigned int ) read_size);
134167 return -1 ;
135168 }
136169 else {
@@ -171,7 +204,7 @@ uint8_t flash_area_erased_val(const struct flash_area* fap) {
171204int flash_area_get_sectors (int fa_id, uint32_t * count, struct flash_sector * sectors) {
172205 mbed::BlockDevice* bd = flash_map_bd[fa_id];
173206
174- // Loop through sectors and collect information on them
207+ /* Loop through sectors and collect information on them */
175208 bd_addr_t offset = 0 ;
176209 *count = 0 ;
177210 while (*count < MCUBOOT_MAX_IMG_SECTORS && bd->is_valid_read (offset, bd->get_read_size ())) {
0 commit comments