diff --git a/boot/bootutil/include/bootutil/mcuboot_status.h b/boot/bootutil/include/bootutil/mcuboot_status.h new file mode 100644 index 00000000..b7349239 --- /dev/null +++ b/boot/bootutil/include/bootutil/mcuboot_status.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022, Laird Connectivity + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef H_MCUBOOT_STATUS_ +#define H_MCUBOOT_STATUS_ + +/* Enumeration representing the states that MCUboot can be in */ +typedef enum +{ + MCUBOOT_STATUS_STARTUP = 0, + MCUBOOT_STATUS_UPGRADING, + MCUBOOT_STATUS_BOOTABLE_IMAGE_FOUND, + MCUBOOT_STATUS_NO_BOOTABLE_IMAGE_FOUND, + MCUBOOT_STATUS_BOOT_FAILED, + MCUBOOT_STATUS_USB_DFU_WAITING, + MCUBOOT_STATUS_USB_DFU_ENTERED, + MCUBOOT_STATUS_USB_DFU_TIMED_OUT, + MCUBOOT_STATUS_SERIAL_DFU_ENTERED, +} mcuboot_status_type_t; + +#if defined(CONFIG_MCUBOOT_ACTION_HOOKS) +extern void mcuboot_status_change(mcuboot_status_type_t status); +#else +#define mcuboot_status_change(_status) do {} while (0) +#endif + +#endif /* H_MCUBOOT_STATUS_ */ diff --git a/boot/bootutil/src/loader.c b/boot/bootutil/src/loader.c index 6f6343c3..27f2e5f1 100644 --- a/boot/bootutil/src/loader.c +++ b/boot/bootutil/src/loader.c @@ -46,6 +46,7 @@ #include "bootutil/fault_injection_hardening.h" #include "bootutil/ramload.h" #include "bootutil/boot_hooks.h" +#include "bootutil/mcuboot_status.h" #ifdef MCUBOOT_ENC_IMAGES #include "bootutil/enc_key.h" @@ -1998,6 +1999,9 @@ context_boot_go(struct boot_loader_state *state, struct boot_rsp *rsp) } #endif + /* Trigger status change callback with upgrading status */ + mcuboot_status_change(MCUBOOT_STATUS_UPGRADING); + /* Iterate over all the images. At this point there are no aborted swaps * and the swap types are determined for each image. By the end of the loop * all required update operations will have been finished. diff --git a/boot/zephyr/Kconfig b/boot/zephyr/Kconfig index 0efd0f0f..c67d9e35 100644 --- a/boot/zephyr/Kconfig +++ b/boot/zephyr/Kconfig @@ -582,6 +582,16 @@ config BOOT_IMAGE_ACCESS_HOOKS_FILE located. If the key file is not there, the build system uses relative path that starts from the zephyr port cmake directory (boot/zephyr/). +config MCUBOOT_ACTION_HOOKS + bool "Enable hooks for responding to MCUboot status changes" + help + This will call a handler when the MCUboot status changes which allows + for some level of user feedback, for instance to change LED status to + indicate a failure, using the callback: + 'void mcuboot_status_change(mcuboot_status_type_t status)' where + 'mcuboot_status_type_t' is listed in + boot/bootutil/include/bootutil/mcuboot_status.h + endmenu config MCUBOOT_DEVICE_SETTINGS diff --git a/boot/zephyr/main.c b/boot/zephyr/main.c index e885fb05..9cd0d0ae 100644 --- a/boot/zephyr/main.c +++ b/boot/zephyr/main.c @@ -33,6 +33,7 @@ #include "bootutil/image.h" #include "bootutil/bootutil.h" #include "bootutil/fault_injection_hardening.h" +#include "bootutil/mcuboot_status.h" #include "flash_map_backend/flash_map_backend.h" #ifdef CONFIG_MCUBOOT_SERIAL @@ -452,6 +453,8 @@ void main(void) (void)rc; + mcuboot_status_change(MCUBOOT_STATUS_STARTUP); + #if (!defined(CONFIG_XTENSA) && DT_HAS_CHOSEN(zephyr_flash_controller)) if (!flash_device_get_binding(DT_LABEL(DT_CHOSEN(zephyr_flash_controller)))) { BOOT_LOG_ERR("Flash device %s not found", @@ -477,6 +480,8 @@ void main(void) gpio_pin_set_dt(&led0, 1); #endif + mcuboot_status_change(MCUBOOT_STATUS_SERIAL_DFU_ENTERED); + BOOT_LOG_INF("Enter the serial recovery mode"); rc = boot_console_init(); __ASSERT(rc == 0, "Error initializing boot console.\n"); @@ -493,6 +498,9 @@ void main(void) #ifdef CONFIG_MCUBOOT_INDICATION_LED gpio_pin_set_dt(&led0, 1); #endif + + mcuboot_status_change(MCUBOOT_STATUS_USB_DFU_ENTERED); + rc = usb_enable(NULL); if (rc) { BOOT_LOG_ERR("Cannot enable USB"); @@ -508,8 +516,13 @@ void main(void) BOOT_LOG_ERR("Cannot enable USB"); } else { BOOT_LOG_INF("Waiting for USB DFU"); + + mcuboot_status_change(MCUBOOT_STATUS_USB_DFU_WAITING); + wait_for_usb_dfu(K_MSEC(CONFIG_BOOT_USB_DFU_WAIT_DELAY_MS)); BOOT_LOG_INF("USB DFU wait time elapsed"); + + mcuboot_status_change(MCUBOOT_STATUS_USB_DFU_TIMED_OUT); } #endif @@ -537,6 +550,9 @@ void main(void) if (fih_not_eq(fih_rc, FIH_SUCCESS)) { BOOT_LOG_ERR("Unable to find bootable image"); + + mcuboot_status_change(MCUBOOT_STATUS_NO_BOOTABLE_IMAGE_FOUND); + FIH_PANIC; } @@ -548,9 +564,14 @@ void main(void) #else BOOT_LOG_INF("Jumping to the first image slot"); #endif + + mcuboot_status_change(MCUBOOT_STATUS_BOOTABLE_IMAGE_FOUND); + ZEPHYR_BOOT_LOG_STOP(); do_boot(&rsp); + mcuboot_status_change(MCUBOOT_STATUS_BOOT_FAILED); + BOOT_LOG_ERR("Never should get here"); while (1) ;