diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..5998ea4 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,41 @@ +# Copyright (c) 2021 ARM Limited. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 + +# Mbed-MCUboot Demo Application + +cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR) + +set(MBED_PATH ${CMAKE_CURRENT_SOURCE_DIR}/mbed-os CACHE INTERNAL "") +set(MCUBOOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/mcuboot CACHE INTERNAL "") +set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "") +set(APP_TARGET application) + +include(${MBED_PATH}/tools/cmake/app.cmake) + +project(${APP_TARGET}) + +add_subdirectory(${MBED_PATH}) +add_subdirectory(${MCUBOOT_PATH}/boot/bootutil/) +add_subdirectory(${MCUBOOT_PATH}/boot/mbed/) # Mbed-MCUboot Port + +add_executable(${APP_TARGET}) + +target_sources(${APP_TARGET} + PUBLIC + main.cpp +) + +target_link_libraries(${APP_TARGET} + PUBLIC + bootutil + mbed-mcuboot + mbed-storage + mbed-os +) + +mbed_set_post_build(${APP_TARGET}) + +option(VERBOSE_BUILD "Have a verbose build process") +if(VERBOSE_BUILD) + set(CMAKE_VERBOSE_MAKEFILE ON) +endif() \ No newline at end of file diff --git a/main.cpp b/main.cpp index 632760e..9f4a558 100644 --- a/main.cpp +++ b/main.cpp @@ -9,6 +9,7 @@ #include "bootutil/bootutil.h" #include "bootutil/image.h" #include "FlashIAP/FlashIAPBlockDevice.h" +#include "blockdevice/SlicingBlockDevice.h" #include "drivers/InterruptIn.h" #define TRACE_GROUP "main" @@ -26,22 +27,53 @@ int main() mbed_trace_init(); mbed_trace_include_filters_set("main,MCUb,BL"); - /** - * Do whatever is needed to verify the firmware is okay - * (eg: self test, connect to server, etc) - * - * And then mark that the update succeeded - */ - //run_self_test(); - int ret = boot_set_confirmed(); - if (ret == 0) { - tr_info("Boot confirmed"); - } else { - tr_error("Failed to confirm boot: %d", ret); - } - InterruptIn btn(DEMO_BUTTON); + // Check if an update has been performed + int swap_type = boot_swap_type(); + int ret; + switch(swap_type) { + case BOOT_SWAP_TYPE_NONE: + tr_info("Regular boot"); + break; + + case BOOT_SWAP_TYPE_REVERT: + // After MCUboot has swapped a (non-permanent) update image + // into the primary slot, it defaults to reverting the image on the NEXT boot. + // This is why we see "[INFO][MCUb]: Swap type: revert" which can be misleading. + // Confirming the CURRENT boot dismisses the reverting. + tr_info("Firmware update applied successfully"); + + // Do whatever is needed to verify the firmware is okay (eg: self test) + // then mark the update as successful. Here we let the user press a button. + tr_info("Press the button to confirm, or reboot to revert the update"); +#if DEMO_BUTTON_ACTIVE_LOW + while (btn) { +#else + while (!btn) { +#endif + sleep(); + } + + ret = boot_set_confirmed(); + if (ret == 0) { + tr_info("Current firmware set as confirmed"); + return 0; + } else { + tr_error("Failed to confirm the firmware: %d", ret); + } + break; + + // Note: Below are intermediate states of MCUboot and + // should never reach the application... + case BOOT_SWAP_TYPE_FAIL: // Unable to boot due to invalid image + case BOOT_SWAP_TYPE_PERM: // Permanent update requested (when signing the image) and to be performed + case BOOT_SWAP_TYPE_TEST: // Revertable update requested and to be performed + case BOOT_SWAP_TYPE_PANIC: // Unrecoverable error + default: + tr_error("Unexpected swap type: %d", swap_type); + } + // Erase secondary slot // On the first boot, the secondary BlockDevice needs to be clean // If the first boot is not normal, please run the erase step, then reboot diff --git a/mbed-os.lib b/mbed-os.lib index f6a52ca..68e51ac 100644 --- a/mbed-os.lib +++ b/mbed-os.lib @@ -1 +1 @@ -https://github.com/ARMmbed/mbed-os/#8ef0a435b2356f8159dea8e427b2935d177309f8 +https://github.com/ARMmbed/mbed-os/#3377f083b3a6bd7a1b45ed2cea5cf083b9007527 diff --git a/mbed_app.json b/mbed_app.json index a3dd71c..ae75e93 100644 --- a/mbed_app.json +++ b/mbed_app.json @@ -2,25 +2,31 @@ "config": { "demo-button": { "macro_name": "DEMO_BUTTON", - "required": true + "required": true, + "value": "BUTTON1" }, "demo-button-active-low": { "help": "true if the button state is low when pressed, high when released", "macro_name": "DEMO_BUTTON_ACTIVE_LOW", "required": false + }, + "mbed_app_start": { + "help": "Use a custom application start address", + "macro_name": "MBED_APP_START", + "required": true } }, "target_overrides": { "*": { "mcuboot.bootloader-build": 0, "target.c_lib": "small", + "target.OUTPUT_EXT": "hex", "mcuboot.log-level": "MCUBOOT_LOG_LEVEL_DEBUG", "mbed-trace.enable": true }, "NRF52840_DK": { - "demo-button": "BUTTON1", "demo-button-active-low": true, - "target.mbed_app_start": "0x21000", + "mbed_app_start": "0x21000", "target.mbed_app_size": "0xBE000", "mcuboot.primary-slot-address": "0x20000", "mcuboot.slot-size": "0xC0000", @@ -31,9 +37,8 @@ "qspif.QSPI_MIN_PROG_SIZE": 4 }, "EP_AGORA": { - "demo-button": "BUTTON1", "demo-button-active-low": true, - "target.mbed_app_start": "0x21000", + "mbed_app_start": "0x21000", "target.mbed_app_size": "0xBE000", "mcuboot.primary-slot-address": "0x20000", "mcuboot.slot-size": "0xC0000", @@ -44,17 +49,14 @@ "qspif.QSPI_MIN_PROG_SIZE": 4 }, "DISCO_L475VG_IOT01A": { - "demo-button": "USER_BUTTON", "demo-button-active-low": true, - "target.mbed_app_start": "0x8021000", + "mbed_app_start": "0x8021000", "target.mbed_app_size": "0xBE000", "mcuboot.primary-slot-address": "0x8020000", "mcuboot.slot-size": "0xC0000", "mcuboot.scratch-address": "0x80E0000", "mcuboot.scratch-size": "0x20000", - "mcuboot.max-img-sectors": "0x180", - "mcuboot.read-granularity": 4, - "qspif.QSPI_MIN_PROG_SIZE": 4 + "mcuboot.max-img-sectors": "0x180" } } } diff --git a/mcuboot.lib b/mcuboot.lib index 2c3e13b..120b416 100644 --- a/mcuboot.lib +++ b/mcuboot.lib @@ -1 +1 @@ -https://github.com/mcu-tools/mcuboot.git \ No newline at end of file +https://github.com/lambda-shuttle/mcuboot.git