From dcd2e6dc9f1bf82de1b2163a83204e57e939a4a0 Mon Sep 17 00:00:00 2001 From: Jamie Smith Date: Sun, 15 Dec 2024 15:13:37 -0800 Subject: [PATCH] Fix missing slicing BD, add workaround for SD cards --- UpdaterApp.cpp | 25 ++++++++++++++++++++----- secondary_bd.cpp | 10 ++++++++-- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/UpdaterApp.cpp b/UpdaterApp.cpp index a6c21ce..6ede64b 100644 --- a/UpdaterApp.cpp +++ b/UpdaterApp.cpp @@ -37,10 +37,8 @@ int main() DigitalIn btn(DEMO_BUTTON); - // Use a buffered block device to allow arbitrary length writes to the underlying BD BlockDevice *secondary_bd = get_secondary_bd(); - BufferedBlockDevice bufferedSecBD(secondary_bd); - int ret = bufferedSecBD.init(); + int ret = secondary_bd->init(); if (ret == 0) { tr_info("Secondary BlockDevice inited"); } else { @@ -58,13 +56,23 @@ int main() } tr_info("Erasing secondary BlockDevice..."); - ret = bufferedSecBD.erase(0, bufferedSecBD.size()); + ret = secondary_bd->erase(0, secondary_bd->size()); if (ret == 0) { tr_info("Secondary BlockDevice erased"); } else { tr_error("Cannot erase secondary BlockDevice: %d", ret); } + // Workaround: for block devices such as MicroSD cards where there is no fixed erase value, + // mcuboot will think that the "magic" region on the secondary BD, which it uses to store + // state info, is corrupt instead of simply not written yet. + // To fix this, we need to actually fill the last 40 bytes with 0xFFs. + if(secondary_bd->get_erase_value() == -1) + { + const std::vector writeBuffer(40, 0xFF); + secondary_bd->program(writeBuffer.data(), secondary_bd->size() - 40, 40); + } + tr_info("> Press button to copy update image to secondary BlockDevice"); while(!DEMO_BUTTON_IS_PRESSED) { @@ -72,7 +80,14 @@ int main() } // Copy the update image from internal flash to secondary BlockDevice - bufferedSecBD.program(&_binary_SimpleApp_update_image_bin_start, 0, SimpleApp_update_image_bin_length); + secondary_bd->program(&_binary_SimpleApp_update_image_bin_start, 0, SimpleApp_update_image_bin_length); + + ret = secondary_bd->deinit(); + if (ret == 0) { + tr_info("Secondary BlockDevice deinited"); + } else { + tr_error("Cannot deinit secondary BlockDevice: %d", ret); + } // Activate the image in the secondary BlockDevice tr_info("> Image copied to secondary BlockDevice, press button to activate"); diff --git a/secondary_bd.cpp b/secondary_bd.cpp index ddb8ad7..38e78be 100644 --- a/secondary_bd.cpp +++ b/secondary_bd.cpp @@ -9,6 +9,7 @@ #include "SlicingBlockDevice.h" #include "FlashIAPBlockDevice.h" +#include "BufferedBlockDevice.h" #if MBED_CONF_APP_SECONDARY_SLOT_IN_FLASH @@ -35,9 +36,14 @@ mbed::BlockDevice* get_secondary_bd(void) { // If this assert fails, there is no block def MBED_ASSERT(default_bd != nullptr); + // mcuboot assumes that the read size of the secondary block device is the same as the read size + // of flash, so use a BufferedBlockDevice to wrap the underlying BD and ensure this is the case. + static mbed::BufferedBlockDevice buffered_bd(default_bd); + // In this case, our flash is much larger than a single image so // slice it into the size of an image slot - //static mbed::SlicingBlockDevice sliced_bd(default_bd, 0x0, MCUBOOT_SLOT_SIZE); - return default_bd; + static mbed::SlicingBlockDevice sliced_bd(&buffered_bd, 0x0, MCUBOOT_SLOT_SIZE); + + return &sliced_bd; } #endif