boot/mcuboot: Add support for MCUboot bootloader

Signed-off-by: Gustavo Henrique Nihei <gustavo.nihei@espressif.com>
This commit is contained in:
Gustavo Henrique Nihei 2021-07-02 11:07:23 -03:00 committed by Alan Carvalho de Assis
parent e6b767f185
commit 794cfd0c5c
10 changed files with 684 additions and 0 deletions

1
boot/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/Kconfig

21
boot/Make.defs Normal file
View File

@ -0,0 +1,21 @@
############################################################################
# apps/boot/Make.defs
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################
include $(wildcard $(APPDIR)/boot/*/Make.defs)

23
boot/Makefile Normal file
View File

@ -0,0 +1,23 @@
############################################################################
# apps/boot/Makefile
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################
MENUDESC = "Bootloader Utilities"
include $(APPDIR)/Directory.mk

2
boot/mcuboot/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/mcuboot
/*.tar.gz

122
boot/mcuboot/Kconfig Normal file
View File

@ -0,0 +1,122 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
menuconfig BOOT_MCUBOOT
bool "MCUboot"
default n
select BCH
---help---
Enable support for the MCUboot bootloader.
if BOOT_MCUBOOT
config MCUBOOT_VERSION
string "MCUboot version"
default "01184bd0361c4128c6382aa9c640b02e7f1422f6"
config MCUBOOT_ENABLE_LOGGING
bool "Enable MCUboot logging"
default n
---help---
Enable MCUboot's logging infrastructure.
config MCUBOOT_BOOTLOADER
bool "MCUboot bootloader application"
default n
select BOARDCTL
select BOARDCTL_BOOT_IMAGE
---help---
MCUboot bootloader application.
config MCUBOOT_UPDATE_AGENT_EXAMPLE
bool "MCUboot update agent example"
default n
depends on NET_TCP
---help---
Example application that implements an update agent that downloads
an application firmware image from a given URL and saves it to the
secondary slot as a pending update.
if MCUBOOT_UPDATE_AGENT_EXAMPLE
config MCUBOOT_UPDATE_AGENT_EXAMPLE_UPDATE_URL
string "URL for update image"
default ""
config MCUBOOT_UPDATE_AGENT_EXAMPLE_DL_BUFFER_SIZE
int "Download buffer size in bytes"
default 512
config MCUBOOT_UPDATE_AGENT_EXAMPLE_DL_VERIFY_MD5
bool "Calculate MD5 of update image"
default n
depends on CODECS_HASH_MD5
config MCUBOOT_UPDATE_AGENT_EXAMPLE_DL_MD5_HASH
string "Expected MD5 sum of update image"
default ""
depends on MCUBOOT_UPDATE_AGENT_EXAMPLE_DL_VERIFY_MD5
endif # MCUBOOT_UPDATE_AGENT_EXAMPLE
config MCUBOOT_SLOT_CONFIRM_EXAMPLE
tristate "MCUboot slot confirm example"
default n
---help---
Example application for confirming a newly installed application
application firmware image using MCUboot public APIs.
This application should be used as the OTA update package of the
MCUBOOT_UPDATE_AGENT_EXAMPLE example.
config MCUBOOT_WATCHDOG
bool "Watchdog feeding support"
default n
depends on WATCHDOG
---help---
This config must be selected in case the Watchdog is enabled while
performing a swap upgrade and the time it takes for a swapping is long
enough to cause an unwanted reset.
config MCUBOOT_WATCHDOG_DEVPATH
string "Watchdog device path"
default "/dev/watchdog0"
depends on MCUBOOT_WATCHDOG
---help---
The path to the watchdog device.
Default: /dev/watchdog0
config MCUBOOT_PRIMARY_SLOT_PATH
string "Application firmware image primary slot path"
default "/dev/ota0"
---help---
The path to the application firmware image primary slot character
device driver.
Default: /dev/ota0
config MCUBOOT_SECONDARY_SLOT_PATH
string "Application firmware image secondary slot path"
default "/dev/ota1"
---help---
The path to the application firmware image secondary slot character
device driver.
Default: /dev/ota1
config MCUBOOT_SCRATCH_PATH
string "Scratch partition path"
default "/dev/otascratch"
---help---
The path to the scratch partition character device driver.
Default: /dev/otascratch
config MCUBOOT_DEFAULT_FLASH_ERASE_STATE
hex "Default flash erase state"
default 0xff
---help---
MCUboot will attempt to retrieve this value from the underlying MTD
driver.
In case of failure, the value from this config will be used as a
fallback.
endif # BOOT_MCUBOOT

34
boot/mcuboot/Make.defs Normal file
View File

@ -0,0 +1,34 @@
############################################################################
# apps/boot/mcuboot/Make.defs
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################
ifeq ($(CONFIG_BOOT_MCUBOOT),y)
CONFIGURED_APPS += $(APPDIR)/boot/mcuboot
# It allows import of NuttX implementation headers for MCUboot interfaces.
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(APPDIR)/boot/mcuboot/mcuboot/boot/nuttx/include}
CXXFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(APPDIR)/boot/mcuboot/mcuboot/boot/nuttx/include}
# It allows import of MCUboot's bootutil library headers.
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(APPDIR)/boot/mcuboot/mcuboot/boot/bootutil/include}
CXXFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(APPDIR)/boot/mcuboot/mcuboot/boot/bootutil/include}
endif

92
boot/mcuboot/Makefile Normal file
View File

@ -0,0 +1,92 @@
############################################################################
# apps/boot/mcuboot/Makefile
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################
include $(APPDIR)/Make.defs
MCUBOOT_VERSION := $(patsubst "%",%,$(CONFIG_MCUBOOT_VERSION))
MCUBOOT_TARBALL = $(MCUBOOT_VERSION).tar.gz
MCUBOOT_UNPACK = mcuboot
MCUBOOT_SRCDIR = $(MCUBOOT_UNPACK)$(DELIM)boot$(DELIM)bootutil$(DELIM)src
DEPPATH += --dep-path $(MCUBOOT_UNPACK)$(DELIM)src
DEPPATH += --dep-path $(MCUBOOT_SRCDIR)
VPATH += :$(MCUBOOT_UNPACK)$(DELIM)src
VPATH += :$(MCUBOOT_SRCDIR)
ifneq ($(CONFIG_MCUBOOT_UPDATE_AGENT_EXAMPLE),)
MAINSRC = mcuboot_agent_main.c
PROGNAME = mcuboot_agent
PRIORITY = SCHED_PRIORITY_DEFAULT
STACKSIZE = $(CONFIG_DEFAULT_TASK_STACKSIZE)
else ifneq ($(CONFIG_MCUBOOT_SLOT_CONFIRM_EXAMPLE),)
MAINSRC = mcuboot_confirm_main.c
PROGNAME = mcuboot_confirm
PRIORITY = SCHED_PRIORITY_DEFAULT
STACKSIZE = $(CONFIG_DEFAULT_TASK_STACKSIZE)
else ifneq ($(CONFIG_MCUBOOT_BOOTLOADER),)
MAINSRC = mcuboot/boot/nuttx/main.c
PROGNAME = mcuboot_loader
PRIORITY = SCHED_PRIORITY_DEFAULT
STACKSIZE = $(CONFIG_DEFAULT_TASK_STACKSIZE)
endif
CSRCS := mcuboot/boot/bootutil/src/boot_record.c \
mcuboot/boot/bootutil/src/bootutil_misc.c \
mcuboot/boot/bootutil/src/bootutil_public.c \
mcuboot/boot/bootutil/src/caps.c \
mcuboot/boot/bootutil/src/encrypted.c \
mcuboot/boot/bootutil/src/fault_injection_hardening.c \
mcuboot/boot/bootutil/src/fault_injection_hardening_delay_rng_mbedtls.c \
mcuboot/boot/bootutil/src/image_ec.c \
mcuboot/boot/bootutil/src/image_ec256.c \
mcuboot/boot/bootutil/src/image_ed25519.c \
mcuboot/boot/bootutil/src/image_rsa.c \
mcuboot/boot/bootutil/src/image_validate.c \
mcuboot/boot/bootutil/src/loader.c \
mcuboot/boot/bootutil/src/swap_misc.c \
mcuboot/boot/bootutil/src/swap_move.c \
mcuboot/boot/bootutil/src/swap_scratch.c \
mcuboot/boot/bootutil/src/tlv.c \
mcuboot/boot/nuttx/src/flash_map_backend/flash_map_backend.c
ifneq ($(CONFIG_MCUBOOT_WATCHDOG),)
CSRCS += mcuboot/boot/nuttx/src/watchdog/watchdog.c
endif
$(MCUBOOT_TARBALL):
$(Q) echo "Downloading MCUboot-$(MCUBOOT_VERSION)"
$(Q) curl -O -L https://github.com/mcu-tools/mcuboot/archive/$(MCUBOOT_TARBALL)
$(MCUBOOT_UNPACK): $(MCUBOOT_TARBALL)
$(Q) echo "Unpacking: $(MCUBOOT_TARBALL) -> $(MCUBOOT_UNPACK)"
$(Q) tar zxf $(MCUBOOT_TARBALL)
$(Q) mv mcuboot-$(MCUBOOT_VERSION) $(MCUBOOT_UNPACK)
$(Q) touch $(MCUBOOT_UNPACK)
context:: $(MCUBOOT_UNPACK)
distclean::
$(call DELFILE, $(MCUBOOT_TARBALL))
$(call DELDIR, $(MCUBOOT_UNPACK))
include $(APPDIR)/Application.mk

52
boot/mcuboot/README.md Normal file
View File

@ -0,0 +1,52 @@
# Boot / `mcuboot` MCUboot
## Description
The NuttX port of MCUboot secure boot library expects that the platform provides a Flash storage with the following partitions:
- `CONFIG_MCUBOOT_PRIMARY_SLOT_PATH`: MTD partition for the application firmware image PRIMARY slot;
- `CONFIG_MCUBOOT_SECONDARY_SLOT_PATH`: MTD partition for the application firmware image SECONDARY slot;
- `CONFIG_MCUBOOT_SCRATCH_PATH`: MTD partition for the Scratch area;
Also, these are optional features that may be enabled:
- `CONFIG_MCUBOOT_WATCHDOG`: If `CONFIG_WATCHDOG` is enabled, MCUboot shall reset the watchdog timer indicated by `CONFIG_MCUBOOT_WATCHDOG_DEVPATH` to the current timeout value, preventing any imminent watchdog timeouts.
The porting layer of MCUboot library consists of the following interfaces:
- `<flash_map_backend/flash_map_backend.h>`, for enabling MCUboot to manage the application firmware image slots in the device storage.
- `<mcuboot_config/mcuboot_config.h>`, for configuration of MCUboot's features.
- `<mcuboot_config/mcuboot_logging.h>`, for providing logging capabilities.
- `<os/os_malloc.h>`, for providing MCUboot access to the OS memory management interfaces.
- `<sysflash/sysflash.h>`, for configuration of the system's flash area organization.
The NuttX port of MCUboot is implemented at application-level and requires minimal knowledge about characteristics of the underlying storage device. This is achieved by means of the `BCH` and `FTL` subsystems, which enable MCUboot to manage MTD partitions via character device drivers using standard POSIX filesystem operations (e.g. `open()` / `close()` / `read()` / `write()`).
## Creating MCUboot-compatible application firmware images
One common use case for MCUboot is to integrate it to a firmware update agent, which is an important component of a secure firmware update subsystem. Through MCUboot APIs an application is able to install a newly received application firmware image and, once this application firmware image is assured to be valid, the application may confirm it as a stable image. In case that application firmware image is deemed bogus, MCUboot provides an API for invalidating that update, which will induce a rollback procedure to the most recent stable application firmware image.
The `CONFIG_MCUBOOT_UPDATE_AGENT_EXAMPLE` example demonstrates this workflow by downloading an application firmware image from a webserver, installing it and triggering the firmware update process for the next boot after a system reset. There is also the `CONFIG_MCUBOOT_SLOT_CONFIRM_EXAMPLE`, which is a fairly simple example that just calls an MCUboot API for confirming the executing application firmware image as stable.
## Using MCUboot on NuttX as a secure boot solution
NuttX port for MCUboot also enables the creation of a secure bootloader application requiring minimal platform-specific implementation. The logical implementation for the secure boot is performed at application-level by the MCUboot library. Once MCUboot validates the application firmware image, it delegates the loading and execution of the application firmware image to a platform-specific routine, which is accessed via `boardctl(BOARDIOC_BOOT_IMAGE)` call. Each platform must then provide an implementation for the `board_boot_image()` for executing the required actions in order to boot a new application firmware image (e.g. deinitialize peripherals, load the Program Counter register with the application firmware image entry point address).
The MCUboot bootloader application may be enabled by selecting the `CONFIG_MCUBOOT_BOOTLOADER` option.
## Assumptions
### IOCTL MTD commands
The implementation of `<flash_map_backend/flash_map_backend.h>` expects that the MTD driver for a given image partition handles the following `ioctl` commands:
- `MTDIOC_GEOMETRY`, for retrieving information about the geometry of the MTD, required for the configuration of the size of each flash area.
- `MTDIOC_ERASESTATE`, for retrieving the byte value of an erased cell of the MTD, required for the implementation of `flash_area_erased_val()` interface.
### Write access alignment
Through `flash_area_align()` interface MCUboot expects that the implementation provides the shortest data length that may be written via `flash_area_write()` interface. The NuttX implementation passes through the `BCH` and `FTL` layers, which appropriately handle the write alignment restrictions of the underlying MTD. So The NuttX implementation of `flash_area_align()` is able to return a fixed value of 1 byte, even if the MTD does not support byte operations.
## Limitations
### `<flash_map_backend/flash_map_backend.h>` functions are not multitasking-safe
MCUboot's documentation imposes no restrictions regarding the usage of its public interfaces, which doesn't mean they are thread-safe.
But, regarding NuttX implementation of the `<flash_map_backend/flash_map_backend.h>`, it is safe to state that they are **not** multitasking-safe. NuttX implementation manages the MTD partitions via character device drivers. As file-descriptors cannot be shared between different tasks, if one task calls `flash_area_open` and another task calls `flash_area_<read/write/close>` passing the same `struct flash_area` instance, it will result in failure.

View File

@ -0,0 +1,291 @@
/****************************************************************************
* apps/boot/mcuboot/mcuboot_agent_main.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <errno.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/boardctl.h>
#include <bootutil/bootutil_public.h>
#ifdef CONFIG_MCUBOOT_UPDATE_AGENT_EXAMPLE_DL_VERIFY_MD5
#include "netutils/md5.h"
#endif
#include "netutils/netlib.h"
#include "netutils/webclient.h"
#include "flash_map_backend/flash_map_backend.h"
#include "sysflash/sysflash.h"
/****************************************************************************
* Preprocessor Definitions
****************************************************************************/
#define DL_BUFFER_SIZE CONFIG_MCUBOOT_UPDATE_AGENT_EXAMPLE_DL_BUFFER_SIZE
#define DL_UPDATE_URL CONFIG_MCUBOOT_UPDATE_AGENT_EXAMPLE_UPDATE_URL
#ifdef CONFIG_MCUBOOT_UPDATE_AGENT_EXAMPLE_DL_VERIFY_MD5
# define MD5_HASH_LENGTH 32
# define MD5_DIGEST_LENGTH 16
# define MD5_EXPECTED_HASH CONFIG_MCUBOOT_UPDATE_AGENT_EXAMPLE_DL_MD5_HASH
#endif
/****************************************************************************
* Private Types
****************************************************************************/
struct download_context_s
{
FAR const struct flash_area *fa;
uint32_t fa_offset;
ssize_t image_size;
#ifdef CONFIG_MCUBOOT_UPDATE_AGENT_EXAMPLE_DL_VERIFY_MD5
MD5_CTX md5_ctx;
#endif
};
/****************************************************************************
* Private Data
****************************************************************************/
static char g_iobuffer[DL_BUFFER_SIZE];
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: header_callback
****************************************************************************/
static int header_callback(FAR const char *line, bool truncated,
FAR void *arg)
{
FAR struct download_context_s *ctx = (FAR struct download_context_s *)arg;
if (ctx->image_size == -1)
{
char *pos = strstr(line, "Content-Length:");
if (pos != NULL)
{
long i;
int errcode;
i = strtol(pos + sizeof("Content-Length:"), NULL, 10);
errcode = errno;
if (errcode == ERANGE)
{
fprintf(stderr, "Error reading \"Content-Length\": %s\n",
strerror(errcode));
}
printf("Firmware Update size: %ld bytes\n", i);
ctx->image_size = i;
}
}
return 0;
}
/****************************************************************************
* Name: sink_callback
****************************************************************************/
static int sink_callback(FAR char **buffer, int offset, int datend,
FAR int *buflen, FAR void *arg)
{
FAR struct download_context_s *ctx = (FAR struct download_context_s *)arg;
uint32_t length = datend - offset;
if (length > 0)
{
uint32_t progress;
flash_area_write(ctx->fa, ctx->fa_offset, &((*buffer)[offset]),
length);
ctx->fa_offset += length;
#ifdef CONFIG_MCUBOOT_UPDATE_AGENT_EXAMPLE_DL_VERIFY_MD5
md5_update(&ctx->md5_ctx,
(FAR const unsigned char *)&((*buffer)[offset]),
length);
#endif
progress = (ctx->fa_offset * 100) / ctx->image_size;
printf("Received: %-8" PRIu32 " of %zd bytes [%" PRIu32 "%%]\n",
ctx->fa_offset, ctx->image_size, progress);
}
return 0;
}
/****************************************************************************
* Name: download_firmware_image
****************************************************************************/
static int download_firmware_image(FAR const char *url)
{
int ret;
struct webclient_context client_ctx;
struct download_context_s dl_ctx;
#ifdef CONFIG_MCUBOOT_UPDATE_AGENT_EXAMPLE_DL_VERIFY_MD5
uint8_t digest[MD5_DIGEST_LENGTH];
char hash[MD5_HASH_LENGTH + 1];
int i;
#endif
dl_ctx.fa = NULL;
dl_ctx.fa_offset = 0;
dl_ctx.image_size = -1;
#ifdef CONFIG_MCUBOOT_UPDATE_AGENT_EXAMPLE_DL_VERIFY_MD5
md5_init(&dl_ctx.md5_ctx);
#endif
webclient_set_defaults(&client_ctx);
client_ctx.method = "GET";
client_ctx.buffer = g_iobuffer;
client_ctx.buflen = sizeof(g_iobuffer);
client_ctx.header_callback = header_callback;
client_ctx.header_callback_arg = &dl_ctx;
client_ctx.sink_callback = sink_callback;
client_ctx.sink_callback_arg = &dl_ctx;
client_ctx.url = url;
ret = flash_area_open(FLASH_AREA_IMAGE_SECONDARY(0), &dl_ctx.fa);
if (ret != OK)
{
fprintf(stderr, "Failed to open flash area\n");
return ret;
}
ret = webclient_perform(&client_ctx);
if (ret != OK)
{
fprintf(stderr, "webclient_perform failed with %d\n", ret);
goto exit_close;
}
#ifdef CONFIG_MCUBOOT_UPDATE_AGENT_EXAMPLE_DL_VERIFY_MD5
md5_final(digest, &dl_ctx.md5_ctx);
for (i = 0; i < MD5_DIGEST_LENGTH; i++)
{
sprintf(&hash[i * 2], "%02x", digest[i]);
}
hash[MD5_HASH_LENGTH] = '\0';
if (strncmp(hash, MD5_EXPECTED_HASH, sizeof(hash)) != 0)
{
fprintf(stderr, "Download checksum verification failure:\n");
fprintf(stderr, "%s Expected\n", MD5_EXPECTED_HASH);
fprintf(stderr, "%s Got\n", hash);
ret = ERROR;
}
else
{
printf("Download checksum verification successful!\n");
}
#endif
exit_close:
flash_area_close(dl_ctx.fa);
return ret;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* mcuboot_agent_main
****************************************************************************/
int main(int argc, FAR char *argv[])
{
int ret;
FAR const char *url;
printf("MCUboot Update Agent example\n");
if (argc > 1)
{
url = argv[1];
}
else
{
url = DL_UPDATE_URL;
}
if (url[0] == '\0')
{
fprintf(stderr, "Usage: mcuboot_agent <URL>\n");
return ERROR;
}
printf("Downloading from %s\n", url);
ret = download_firmware_image(url);
if (ret != OK)
{
fprintf(stderr, "Application Image download failure.\n");
fprintf(stderr, "Update aborted.\n");
return ERROR;
}
printf("Application Image successfully downloaded!\n");
boot_set_pending_multi(0, 0);
printf("Requested update for next boot. Restarting...\n");
fflush(stdout);
fflush(stderr);
usleep(1000);
boardctl(BOARDIOC_RESET, EXIT_SUCCESS);
return OK;
}

View File

@ -0,0 +1,46 @@
/****************************************************************************
* apps/boot/mcuboot/mcuboot_confirm_main.c
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdio.h>
#include <bootutil/bootutil_public.h>
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* mcuboot_confirm_main
****************************************************************************/
int main(int argc, FAR char *argv[])
{
boot_set_confirmed_multi(0);
printf("Application Image successfully confirmed!\n");
return 0;
}