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_sources(retention.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_RETENTION_BOOT_MODE bootmode.c)
|
||||
|
|
|
@ -5,10 +5,10 @@ menuconfig RETENTION
|
|||
bool "Retention support"
|
||||
depends on CRC
|
||||
depends on RETAINED_MEM
|
||||
depends on DT_HAS_ZEPHYR_DATA_RETENTION_ENABLED
|
||||
depends on DT_HAS_ZEPHYR_RETENTION_ENABLED
|
||||
help
|
||||
Enables support for the data retention system, which uses retained
|
||||
memory drivers.
|
||||
Enables support for the retention system, which uses retained memory
|
||||
drivers.
|
||||
|
||||
if RETENTION
|
||||
|
||||
|
@ -16,8 +16,8 @@ config RETENTION_INIT_PRIORITY
|
|||
int "Retention devices init priority"
|
||||
default 86
|
||||
help
|
||||
Data retention devices initialization priority (must be higher than
|
||||
init priorities for retained memory drivers.
|
||||
Retention device initialization priority (must be higher than init
|
||||
priorities for retained memory drivers.
|
||||
|
||||
config RETENTION_BUFFER_SIZE
|
||||
int "Retention stack buffer sizes"
|
||||
|
@ -27,6 +27,22 @@ config RETENTION_BUFFER_SIZE
|
|||
Size of buffers (stack based) used when reading and writing data
|
||||
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-str = retention
|
||||
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