Skip to content

Commit

Permalink
retention: Add boot mode system
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
nordicjm authored and carlescufi committed Apr 24, 2023
1 parent 8f859a0 commit 7e11b63
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 5 deletions.
78 changes: 78 additions & 0 deletions include/zephyr/retention/bootmode.h
Original file line number Diff line number Diff line change
@@ -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_ */
1 change: 1 addition & 0 deletions subsys/retention/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@

zephyr_library()
zephyr_library_sources(retention.c)
zephyr_library_sources_ifdef(CONFIG_RETENTION_BOOT_MODE bootmode.c)
26 changes: 21 additions & 5 deletions subsys/retention/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ 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

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"
Expand All @@ -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"
Expand Down
46 changes: 46 additions & 0 deletions subsys/retention/bootmode.c
Original file line number Diff line number Diff line change
@@ -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);
}

0 comments on commit 7e11b63

Please sign in to comment.