Skip to content

Commit ee1be0d

Browse files
samples: Add a sample for runtime chosen image
A sample for runtime chose image on FRDM K64F. It provides implementation for Zephyr flash_area_open_custom(), so the right flash map implementation is used, and MCUboot flash_map_id_get_next() and flash_map_id_get_current() to prioritize sources. It should show what is expected from an application to be able to use non-flash sources for images. In this sample, one can influence from which slot image will be loaded by pressing a button on the board. For more details on how to build and test the samples, check the provided README.md. Signed-off-by: Ederson de Souza <[email protected]>
1 parent 665721f commit ee1be0d

File tree

9 files changed

+167
-0
lines changed

9 files changed

+167
-0
lines changed

boot/zephyr/CMakeLists.txt

+6
Original file line numberDiff line numberDiff line change
@@ -428,6 +428,12 @@ if(CONFIG_BOOT_MAX_IMG_SECTORS_AUTO)
428428
endif()
429429
endif()
430430

431+
if(BUILD_RUNTIME_SOURCE_SAMPLE)
432+
zephyr_library_sources(
433+
${MCUBOOT_DIR}/samples/runtime-source/zephyr/flash_map_dispatcher.c
434+
)
435+
endif()
436+
431437
if(SYSBUILD)
432438
if(CONFIG_SINGLE_APPLICATION_SLOT OR CONFIG_BOOT_FIRMWARE_LOADER OR CONFIG_BOOT_SWAP_USING_SCRATCH OR CONFIG_BOOT_SWAP_USING_MOVE OR CONFIG_BOOT_UPGRADE_ONLY OR CONFIG_BOOT_DIRECT_XIP OR CONFIG_BOOT_RAM_LOAD)
433439
# TODO: RAM LOAD support

boot/zephyr/flash_map_extended.c

+4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@
1414
#include <flash_map_backend/flash_map_backend.h>
1515
#include <sysflash/sysflash.h>
1616

17+
#if defined(CONFIG_FLASH_RUNTIME_SOURCES)
18+
#include <flash_runtime_sources.h>
19+
#endif
20+
1721
#include "bootutil/bootutil_log.h"
1822

1923
BOOT_LOG_MODULE_DECLARE(mcuboot);
+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# Runtime chosen image sample application
2+
3+
This sample demonstrates how to use a non flash storage to retrieve the image
4+
being booted. It was tested on a FRDM K64F. Both slots are used to store two
5+
different images. The image to be booted is selected based on a button press.
6+
7+
## Build
8+
9+
Build mcuboot. First, ensure ZEPHYR_SDK_INSTALL_DIR is defined. From the
10+
mcuboot directory, run the following commands:
11+
12+
```
13+
source <path-to-zephyr>/zephyr-env.sh
14+
15+
west build -p -b frdm_k64f boot/zephyr/ -- -DBUILD_RUNTIME_SOURCE_SAMPLE=1 \
16+
-DEXTRA_CONF_FILE="../../samples/runtime-source/zephyr/sample.conf"
17+
-DEXTRA_DTC_OVERLAY_FILE=../../samples/runtime-source/zephyr/boards/frdm_k64f.overlay
18+
19+
west build -t flash
20+
```
21+
22+
Then, build the sample application to be loaded. We need to build it twice, one
23+
for each slot. From the sample
24+
app directory (mcuboot/samples/non-flash-source/zephyr/app), run:
25+
26+
```
27+
west build -p -b frdm_k64f .
28+
west flash
29+
```
30+
31+
Then change the overlay file to use the second slot. For instance, open
32+
`boards/frdm_k64f.overlay` and change the line:
33+
34+
```
35+
zephyr,code-partition = &slot0_partition;
36+
37+
```
38+
39+
to:
40+
41+
```
42+
zephyr,code-partition = &slot1_partition;
43+
```
44+
45+
And build and flash again:
46+
47+
```
48+
west build -b frdm_k64f .
49+
west flash
50+
```
51+
52+
## Run
53+
54+
Open a serial terminal to see the output and reset the board. It shall boot the
55+
image on slot0 by default. By keeping the SW2 button pressed during reset, the
56+
bootloader will randomly select the image to be booted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
5+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
6+
project(non_flash_backend_app)
7+
8+
if (NOT DEFINED FROM_WHO)
9+
set(FROM_WHO Zephyr)
10+
endif()
11+
12+
target_compile_definitions(app PRIVATE "-DMCUBOOT_HELLO_WORLD_FROM=\"${FROM_WHO}\"")
13+
14+
target_sources(app PRIVATE src/main.c)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/ {
2+
chosen {
3+
zephyr,code-partition = &slot0_partition;
4+
};
5+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
CONFIG_BOOTLOADER_MCUBOOT=y
2+
3+
CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="./bootloader/mcuboot/root-rsa-2048.pem"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* Copyright (c) 2017 Linaro, Ltd.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/kernel.h>
8+
#include <zephyr/sys/printk.h>
9+
10+
int main(void)
11+
{
12+
printk("Hello World from %s on %s, slot %s!\n",
13+
MCUBOOT_HELLO_WORLD_FROM, CONFIG_BOARD,
14+
DT_PROP(DT_CHOSEN(zephyr_code_partition), label));
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright (c) 2024 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <flash_map_backend/flash_map_backend.h>
8+
#include <zephyr/drivers/gpio.h>
9+
#include <zephyr/kernel.h>
10+
#include <zephyr/random/random.h>
11+
12+
#define SW1_NODE DT_ALIAS(sw1)
13+
#if DT_NODE_HAS_STATUS(SW1_NODE, okay)
14+
static struct gpio_dt_spec sw1_spec = GPIO_DT_SPEC_GET(SW1_NODE, gpios);
15+
#endif
16+
17+
static int curr_idx = -1;
18+
19+
static uint8_t known_ids[] = {
20+
FIXED_PARTITION_ID(slot0_partition),
21+
FIXED_PARTITION_ID(slot1_partition),
22+
};
23+
24+
bool
25+
flash_map_id_get_next(uint8_t *id, bool reset)
26+
{
27+
if (reset) {
28+
curr_idx = 0;
29+
#if DT_NODE_HAS_STATUS(SW1_NODE, okay)
30+
if (gpio_pin_configure_dt(&sw1_spec, GPIO_INPUT) == 0) {
31+
if (gpio_pin_get_dt(&sw1_spec) == 1) {
32+
curr_idx = sys_rand8_get() % ARRAY_SIZE(known_ids);
33+
printk("Booting from curr_idx = %d\n", curr_idx);
34+
}
35+
}
36+
#endif
37+
} else {
38+
curr_idx++;
39+
}
40+
41+
if (curr_idx >= ARRAY_SIZE(known_ids)) {
42+
return false;
43+
}
44+
45+
*id = known_ids[curr_idx];
46+
47+
return true;
48+
}
49+
50+
bool
51+
flash_map_id_get_current(uint8_t *id)
52+
{
53+
if (curr_idx == -1 || curr_idx >= ARRAY_SIZE(known_ids)) {
54+
return false;
55+
}
56+
57+
*id = known_ids[curr_idx];
58+
59+
return true;
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
CONFIG_FLASH_RUNTIME_SOURCES=y
2+
CONFIG_BOOT_SIGNATURE_TYPE_RSA=y
3+
CONFIG_TEST_RANDOM_GENERATOR=y
4+
CONFIG_ENTROPY_GENERATOR=y

0 commit comments

Comments
 (0)