Skip to content

Commit cf7b016

Browse files
ahasztagmaciejpietras
authored andcommitted
suit: Add "enter recovery button"
This commit adds code allowing to enter SUIT foreground update (in most cases the same as recovery) mode via keeping a button pressed during system bootup. Signed-off-by: Artur Hadasz <[email protected]>
1 parent 76d1c8d commit cf7b016

File tree

6 files changed

+108
-0
lines changed

6 files changed

+108
-0
lines changed

samples/suit/smp_transfer/sysbuild/recovery.overlay

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,9 @@
55
*/
66

77
#include "../boards/nrf54h20dk_nrf54h20_cpuapp_common.dtsi"
8+
9+
/ {
10+
chosen {
11+
recovery-button = &button0;
12+
};
13+
};

subsys/suit/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ add_subdirectory_ifdef(CONFIG_SUIT_ENVELOPE_INFO envelope_info)
2121
add_subdirectory_ifdef(CONFIG_SUIT_EXECUTION_MODE execution_mode)
2222
add_subdirectory_ifdef(CONFIG_SUIT_VALIDATOR validator)
2323
add_subdirectory_ifdef(CONFIG_SUIT_EVENTS events)
24+
add_subdirectory_ifdef(CONFIG_SUIT_RECOVERY_BUTTON recovery_button)

subsys/suit/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,7 @@ rsource "execution_mode/Kconfig"
198198
rsource "memory_layout/Kconfig"
199199
rsource "validator/Kconfig"
200200
rsource "events/Kconfig"
201+
rsource "recovery_button/Kconfig"
201202

202203
# Configure SUIT_LOG_LEVEL
203204
module = SUIT
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#
2+
# Copyright (c) 2024 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
zephyr_library()
8+
zephyr_library_sources(src/suit_recovery_button.c)
9+
10+
zephyr_library_link_libraries(suit_platform_err)
11+
zephyr_library_link_libraries(suit_utils)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#
2+
# Copyright (c) 2024 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
config SUIT_RECOVERY_BUTTON
8+
bool "Enable SUIT enter recovery button checking on startup"
9+
depends on $(dt_chosen_enabled,recovery-button)
10+
select SSF_SUIT_SERVICE_ENABLED
11+
help
12+
This will make the firmware check if the recovery button specified in the
13+
device tree is pressed on startup. If it is, the firmware will enter
14+
the "foreground update mode", in which the same SUIT manifests are booted
15+
as in case of the recovery mode.
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/*
2+
* Copyright (c) 2024 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
#include <zephyr/kernel.h>
8+
#include <zephyr/drivers/gpio.h>
9+
#include <nrfx_gpiote.h>
10+
#include <sdfw/sdfw_services/suit_service.h>
11+
12+
#define RECOVERY_BUTTON_NODE DT_CHOSEN(recovery_button)
13+
#define RECOVERY_BUTTON_PIN DT_GPIO_PIN(RECOVERY_BUTTON_NODE, gpios)
14+
#define RECOVERY_BUTTON_PORT_NUM DT_PROP(DT_GPIO_CTLR(RECOVERY_BUTTON_NODE, gpios), port)
15+
#define RECOVERY_BUTTON_FLAGS DT_GPIO_FLAGS(RECOVERY_BUTTON_NODE, gpios)
16+
17+
#define RECOVERY_BUTTON_ABS_PIN NRF_GPIO_PIN_MAP(RECOVERY_BUTTON_PORT_NUM, RECOVERY_BUTTON_PIN)
18+
#define RECOVERY_BUTTON_PULL (RECOVERY_BUTTON_FLAGS & GPIO_PULL_UP ? NRF_GPIO_PIN_PULLUP : \
19+
RECOVERY_BUTTON_FLAGS & GPIO_PULL_DOWN ? NRF_GPIO_PIN_PULLDOWN : \
20+
NRF_GPIO_PIN_NOPULL)
21+
22+
#define RECOVERY_BUTTON_PRESSED(pin_value) (RECOVERY_BUTTON_FLAGS & GPIO_ACTIVE_LOW ? (!pin_value) \
23+
: pin_value)
24+
25+
BUILD_ASSERT(DT_NODE_EXISTS(DT_CHOSEN(recovery_button)), "No recovery button chosen in dts");
26+
27+
static int recovery_button_check(void)
28+
{
29+
suit_boot_mode_t mode = SUIT_BOOT_MODE_INVOKE_RECOVERY;
30+
suit_ssf_err_t err = SUIT_PLAT_SUCCESS;
31+
int ret = 0;
32+
33+
err = suit_boot_mode_read(&mode);
34+
35+
if (err != SUIT_PLAT_SUCCESS) {
36+
suit_invoke_confirm(-EPIPE);
37+
return -EPIPE;
38+
}
39+
40+
/** Using the recovery button makes sense in two cases:
41+
* 1. From a companion application during SUIT manifest processing while the device
42+
* is booting(mode == SUIT_BOOT_MODE_INVOKE).
43+
* 2. From the main application, when the device is already booted
44+
* (mode == SUIT_BOOT_MODE_POST_INVOKE).
45+
*/
46+
if (mode == SUIT_BOOT_MODE_INVOKE
47+
|| mode == SUIT_BOOT_MODE_POST_INVOKE) {
48+
nrf_gpio_pin_dir_t dir = NRF_GPIO_PIN_DIR_INPUT;
49+
nrf_gpio_pin_input_t input = NRF_GPIO_PIN_INPUT_CONNECT;
50+
nrf_gpio_pin_pull_t pull = RECOVERY_BUTTON_PULL;
51+
52+
nrf_gpio_reconfigure(RECOVERY_BUTTON_ABS_PIN, &dir, &input, &pull, NULL, NULL);
53+
54+
uint32_t pin_value = nrf_gpio_pin_read(RECOVERY_BUTTON_ABS_PIN);
55+
56+
if (RECOVERY_BUTTON_PRESSED(pin_value)) {
57+
err = suit_foreground_dfu_required();
58+
}
59+
}
60+
61+
if (err != SUIT_PLAT_SUCCESS) {
62+
ret = -EPIPE;
63+
}
64+
65+
if (mode == SUIT_BOOT_MODE_INVOKE
66+
|| mode == SUIT_BOOT_MODE_INVOKE_FOREGROUND_DFU
67+
|| mode == SUIT_BOOT_MODE_INVOKE_RECOVERY) {
68+
(void)suit_invoke_confirm(ret);
69+
}
70+
71+
return ret;
72+
}
73+
74+
SYS_INIT(recovery_button_check, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);

0 commit comments

Comments
 (0)