This is an automated email from the ASF dual-hosted git repository.

kasjer pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git


The following commit(s) were added to refs/heads/master by this push:
     new bd19ed348 tinyusb/msc_fat_view: Erase each flash sector only once
bd19ed348 is described below

commit bd19ed348ac8d16fce0d7fb1a9f8a33decd8a0e7
Author: Jerzy Kasenberg <[email protected]>
AuthorDate: Mon Oct 19 15:21:40 2026 +0200

    tinyusb/msc_fat_view: Erase each flash sector only once
    
    Update handler checked every 512 byte disk sector and erased it
    if it was not empty. Erase works on whole flash sector (usually
    several kB) so it also erased disk sectors already written to the
    same flash sector. When beginning of flash sector was already
    empty (e.g. image header after previous failed upload) and further
    part was not, image header was erased and new image was rejected
    as invalid. Since that leaves slot in the same state, all following
    uploads failed as well.
    
    Now flash sectors are tracked with flash_area_getnext_sector() and
    each one is erased (if not empty) before first disk sector is
    written to it.
    
    Assisted-by: Claude:claude-opus-5-5
    Signed-off-by: Jerzy Kasenberg <[email protected]>
---
 hw/usb/tinyusb/msc_fat_view/src/update_handler.c | 32 +++++++++++++++++++++---
 1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/hw/usb/tinyusb/msc_fat_view/src/update_handler.c 
b/hw/usb/tinyusb/msc_fat_view/src/update_handler.c
index 9f9829efc..d2da32094 100644
--- a/hw/usb/tinyusb/msc_fat_view/src/update_handler.c
+++ b/hw/usb/tinyusb/msc_fat_view/src/update_handler.c
@@ -53,6 +53,10 @@ static medium_state_t medium_state;
 struct unallocated_write {
     uint32_t first_sector;
     uint32_t last_sector;
+    /* Last flash sector prepared for writing (-1 none yet) */
+    int flash_sector_id;
+    /* Offset in flash area up to which flash is ready for writing */
+    uint32_t erased_limit;
     enum {
         NOT_TOUCHED_YET = 0,
         WRITE_IN_PROGRESS = 1,
@@ -123,6 +127,7 @@ image_write_sector(struct msc_fat_view_write_handler 
*handler, uint32_t sector,
 {
 #ifdef FLASH_AREA_IMAGE
     const struct flash_area *fa;
+    struct flash_area flash_sector;
     uint32_t write_offset;
     int rc;
 
@@ -149,6 +154,8 @@ image_write_sector(struct msc_fat_view_write_handler 
*handler, uint32_t sector,
             MSC_FAT_VIEW_LOG_INFO("Image writing detected\n");
             unallocated_write.first_sector = sector;
             unallocated_write.last_sector = sector;
+            unallocated_write.flash_sector_id = -1;
+            unallocated_write.erased_limit = 0;
         }
     } else if (unallocated_write.write_status == WRITE_IN_PROGRESS) {
         if (sector != unallocated_write.last_sector + 1) {
@@ -162,11 +169,30 @@ image_write_sector(struct msc_fat_view_write_handler 
*handler, uint32_t sector,
     }
     if (unallocated_write.write_status == WRITE_IN_PROGRESS) {
         write_offset = (sector - unallocated_write.first_sector) * SECTOR_SIZE;
-        if (!hal_flash_isempty_no_buf(fa->fa_device_id, fa->fa_off + 
write_offset, SECTOR_SIZE)) {
-            flash_area_erase(fa, write_offset, SECTOR_SIZE);
+        /*
+         * Flash sectors are usually bigger than disk sector. Erase each flash
+         * sector (if needed) only once, when first disk sector falls into it.
+         * Erasing it later would destroy data that was already written.
+         */
+        rc = 0;
+        while (rc == 0 && write_offset + SECTOR_SIZE > 
unallocated_write.erased_limit) {
+            rc = flash_area_getnext_sector(FLASH_AREA_IMAGE,
+                                           &unallocated_write.flash_sector_id,
+                                           &flash_sector);
+            if (rc == 0) {
+                if (!hal_flash_isempty_no_buf(flash_sector.fa_device_id,
+                                              flash_sector.fa_off,
+                                              flash_sector.fa_size)) {
+                    rc = hal_flash_erase_sector(flash_sector.fa_device_id,
+                                                flash_sector.fa_off);
+                }
+                unallocated_write.erased_limit =
+                    flash_sector.fa_off + flash_sector.fa_size - fa->fa_off;
+            }
         }
 
-        if ((rc = flash_area_write(fa, write_offset, buffer, SECTOR_SIZE)) < 
0) {
+        if (rc != 0 ||
+            (rc = flash_area_write(fa, write_offset, buffer, SECTOR_SIZE)) < 
0) {
             MSC_FAT_VIEW_LOG_ERROR("Flash write error, following writes will 
be rejected %d 0x%08x\n",
                                    rc, fa->fa_off + write_offset);
             unallocated_write.write_status = WRITE_EXCEEDED_SPACE;

Reply via email to