@@ -51,6 +51,11 @@ BUILD_ASSERT(FIXED_PARTITION_EXISTS(SLOT4_PARTITION) &&
51
51
"Missing partitions?" );
52
52
#endif
53
53
54
+ #if defined(CONFIG_MCUMGR_GRP_IMG_IMAGE_SKIP_ERASED_SECTORS )
55
+ BUILD_ASSERT (CONFIG_MCUMGR_GRP_IMG_IMAGE_SKIP_ERASED_SECTORS_BUFFER_SIZE % 4 == 0 ,
56
+ "CONFIG_MCUMGR_GRP_IMG_IMAGE_SKIP_ERASED_SECTORS_BUFFER_SIZE must be multiple of 4" );
57
+ #endif
58
+
54
59
/**
55
60
* Determines if the specified area of flash is completely unwritten.
56
61
*
@@ -274,6 +279,89 @@ int img_mgmt_vercmp(const struct image_version *a, const struct image_version *b
274
279
return 0 ;
275
280
}
276
281
282
+ #if defined(CONFIG_MCUMGR_GRP_IMG_IMAGE_SKIP_ERASED_SECTORS )
283
+ static int img_mgmt_erase_unerased_slot_data (const struct flash_area * fa )
284
+ {
285
+ struct flash_pages_info fpi ;
286
+ int rc ;
287
+ off_t off = 0 ;
288
+ uint8_t erased_val ;
289
+ uint32_t erased_val_32 ;
290
+
291
+ assert (fa -> fa_size % 4 == 0 );
292
+ erased_val = flash_area_erased_val (fa );
293
+ erased_val_32 = ERASED_VAL_32 (erased_val );
294
+
295
+ while (off < fa -> fa_size ) {
296
+ uint32_t data [CONFIG_MCUMGR_GRP_IMG_IMAGE_SKIP_ERASED_SECTORS_BUFFER_SIZE ];
297
+ off_t addr ;
298
+ int bytes_to_read ;
299
+ int i ;
300
+ bool needs_erase = false;
301
+
302
+ rc = flash_get_page_info_by_offs (fa -> fa_dev , (fa -> fa_off + off ), & fpi );
303
+
304
+ if (rc ) {
305
+ return rc ;
306
+ }
307
+
308
+ for (addr = 0 ; addr < fpi .size ; addr += sizeof (data )) {
309
+ if ((fpi .size - addr ) < sizeof (data )) {
310
+ bytes_to_read = (fpi .size - addr );
311
+ } else {
312
+ bytes_to_read = sizeof (data );
313
+ }
314
+
315
+ rc = flash_area_read (fa , (addr + off ), data , bytes_to_read );
316
+
317
+ if (rc < 0 ) {
318
+ LOG_ERR ("Failed to read data from flash area: %d" , rc );
319
+ return rc ;
320
+ }
321
+
322
+ for (i = 0 ; i < bytes_to_read / sizeof (erased_val_32 ); i ++ ) {
323
+ if (data [i ] != erased_val_32 ) {
324
+ needs_erase = true;
325
+ goto perform_erase ;
326
+ }
327
+ }
328
+ }
329
+
330
+ perform_erase :
331
+ if (needs_erase ) {
332
+ rc = flash_area_flatten (fa , off , fpi .size );
333
+
334
+ if (rc != 0 ) {
335
+ LOG_ERR ("Failed to erase flash area: %d" , rc );
336
+ return rc ;
337
+ }
338
+ }
339
+
340
+ off += fpi .size ;
341
+ }
342
+
343
+ return 0 ;
344
+ }
345
+
346
+ int img_mgmt_erase_pending_upload_slot (void )
347
+ {
348
+ const struct flash_area * fa ;
349
+ int rc ;
350
+
351
+ rc = flash_area_open (g_img_mgmt_state .area_id , & fa );
352
+
353
+ if (rc ) {
354
+ goto done ;
355
+ }
356
+
357
+ rc = img_mgmt_erase_unerased_slot_data (fa );
358
+ flash_area_close (fa );
359
+
360
+ done :
361
+ return rc ;
362
+ }
363
+ #endif
364
+
277
365
int img_mgmt_erase_slot (int slot )
278
366
{
279
367
const struct flash_area * fa ;
@@ -291,6 +379,9 @@ int img_mgmt_erase_slot(int slot)
291
379
return IMG_MGMT_ERR_FLASH_OPEN_FAILED ;
292
380
}
293
381
382
+ #if defined(CONFIG_MCUMGR_GRP_IMG_IMAGE_SKIP_ERASED_SECTORS )
383
+ rc = img_mgmt_erase_unerased_slot_data (fa );
384
+ #else
294
385
rc = img_mgmt_flash_check_empty_inner (fa );
295
386
296
387
if (rc == 0 ) {
@@ -306,6 +397,7 @@ int img_mgmt_erase_slot(int slot)
306
397
*/
307
398
rc = 0 ;
308
399
}
400
+ #endif
309
401
310
402
flash_area_close (fa );
311
403
0 commit comments