retention: Add boot mode system

Adds a boot mode system which allows for redirecting the boot
target of a device depending upon the state of a retained value.

Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
This commit is contained in:
Jamie McCrae 2023-02-23 14:36:45 +00:00 committed by Carles Cufí
commit 7e11b6392b
4 changed files with 146 additions and 5 deletions

View file

@ -0,0 +1,78 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Public API for boot mode interface
*/
#ifndef ZEPHYR_INCLUDE_RETENTION_BOOTMODE_
#define ZEPHYR_INCLUDE_RETENTION_BOOTMODE_
#include <stdint.h>
#include <stddef.h>
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/types.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Boot mode interface
* @defgroup boot_mode_interface Boot mode interface
* @ingroup retention
* @{
*/
enum BOOT_MODE_TYPES {
/** Default (normal) boot, to user application */
BOOT_MODE_TYPE_NORMAL = 0x00,
/** Bootloader boot mode (e.g. serial recovery for MCUboot) */
BOOT_MODE_TYPE_BOOTLOADER,
};
/**
* @brief Checks if the boot mode of the device is set to a specific value.
*
* @param boot_mode Expected boot mode to check.
*
* @retval 1 If successful and boot mode matches.
* @retval 0 If boot mode does not match.
* @retval -errno Error code code.
*/
int bootmode_check(uint8_t boot_mode);
/**
* @brief Sets boot mode of device.
*
* @param boot_mode Boot mode value to set.
*
* @retval 0 If successful.
* @retval -errno Error code code.
*/
int bootmode_set(uint8_t boot_mode);
/**
* @brief Clear boot mode value (sets to 0) - which corresponds to
* #BOOT_MODE_TYPE_NORMAL.
*
* @retval 0 If successful.
* @retval -errno Error code code.
*/
int bootmode_clear(void);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_RETENTION_BOOTMODE_ */

View file

@ -2,3 +2,4 @@
zephyr_library() zephyr_library()
zephyr_library_sources(retention.c) zephyr_library_sources(retention.c)
zephyr_library_sources_ifdef(CONFIG_RETENTION_BOOT_MODE bootmode.c)

View file

@ -5,10 +5,10 @@ menuconfig RETENTION
bool "Retention support" bool "Retention support"
depends on CRC depends on CRC
depends on RETAINED_MEM depends on RETAINED_MEM
depends on DT_HAS_ZEPHYR_DATA_RETENTION_ENABLED depends on DT_HAS_ZEPHYR_RETENTION_ENABLED
help help
Enables support for the data retention system, which uses retained Enables support for the retention system, which uses retained memory
memory drivers. drivers.
if RETENTION if RETENTION
@ -16,8 +16,8 @@ config RETENTION_INIT_PRIORITY
int "Retention devices init priority" int "Retention devices init priority"
default 86 default 86
help help
Data retention devices initialization priority (must be higher than Retention device initialization priority (must be higher than init
init priorities for retained memory drivers. priorities for retained memory drivers.
config RETENTION_BUFFER_SIZE config RETENTION_BUFFER_SIZE
int "Retention stack buffer sizes" int "Retention stack buffer sizes"
@ -27,6 +27,22 @@ config RETENTION_BUFFER_SIZE
Size of buffers (stack based) used when reading and writing data Size of buffers (stack based) used when reading and writing data
from/to the retention device. from/to the retention device.
menu "Retention modules"
config RETENTION_BOOT_MODE
bool "Boot mode"
help
Adds a boot mode system that allows for changing execution flow
depending upon the value of a boot mode parameter. Can be used for
e.g. button-less bootloader serial recovery mode entering from the
application.
In order to use this, a retention area with at least 1 usable user
byte must be created and set as the "zephyr,boot-mode" chosen node
via device tree.
endmenu
module = RETENTION module = RETENTION
module-str = retention module-str = retention
source "subsys/logging/Kconfig.template.log_config" source "subsys/logging/Kconfig.template.log_config"

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2023, Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/devicetree.h>
#include <zephyr/retention/retention.h>
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(bootmode, CONFIG_RETENTION_LOG_LEVEL);
static const struct device *boot_mode_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_boot_mode));
int bootmode_check(uint8_t boot_mode)
{
int rc;
rc = retention_is_valid(boot_mode_dev);
if (rc == 1) {
uint8_t stored_mode;
rc = retention_read(boot_mode_dev, 0, &stored_mode, sizeof(stored_mode));
/* Only check if modes match if there was no error, otherwise return the error */
if (rc == 0) {
if (stored_mode == boot_mode) {
rc = 1;
}
}
}
return rc;
}
int bootmode_set(uint8_t boot_mode)
{
return retention_write(boot_mode_dev, 0, &boot_mode, sizeof(boot_mode));
}
int bootmode_clear(void)
{
return retention_clear(boot_mode_dev);
}