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:
parent
8f859a065c
commit
7e11b6392b
4 changed files with 146 additions and 5 deletions
78
include/zephyr/retention/bootmode.h
Normal file
78
include/zephyr/retention/bootmode.h
Normal 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_ */
|
|
@ -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)
|
||||||
|
|
|
@ -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"
|
||||||
|
|
46
subsys/retention/bootmode.c
Normal file
46
subsys/retention/bootmode.c
Normal 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);
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue