Skip to content

Commit 57b5dc6

Browse files
Update for Mbed CE. Switch to including image to install directly into the program
1 parent 4f206b1 commit 57b5dc6

File tree

16 files changed

+416
-276
lines changed

16 files changed

+416
-276
lines changed

.circleci/config.yml

Lines changed: 0 additions & 18 deletions
This file was deleted.

.github/workflows/compile.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Example GitHub Actions workflow which provides a CI build for your Mbed CE project.
2+
3+
name: Test that this Mbed project compiles
4+
5+
on: push
6+
7+
jobs:
8+
compile:
9+
runs-on: ubuntu-latest
10+
container: ghcr.io/armmbed/mbed-os-env:master-latest
11+
12+
strategy:
13+
matrix:
14+
mbed_target:
15+
# Change the below to match the target(s) you want to compile the project for.
16+
- K64F
17+
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@v4
21+
with:
22+
submodules: recursive
23+
24+
- name: Install python3-venv
25+
run: |
26+
apt-get update
27+
apt-get install -y python3-venv
28+
29+
- name: Build project for ${{ matrix.mbed_target }}
30+
run: |
31+
mkdir build && cd build
32+
cmake .. -GNinja -DMBED_TARGET=${{ matrix.mbed_target }}
33+
ninja

.gitignore

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,41 @@
1-
.build
2-
.mbed
3-
projectfiles
4-
*.py*
1+
# Private key file
2+
signing-keys.pem
3+
4+
# CLion build dirs
5+
cmake-build-*/
6+
7+
# User-specific CLion stuff
8+
.idea/**/workspace.xml
9+
.idea/**/tasks.xml
10+
.idea/**/usage.statistics.xml
11+
.idea/**/dictionaries
12+
.idea/**/shelf
13+
.idea/runConfigurations
14+
15+
# Generated CLion files
16+
.idea/**/contentModel.xml
17+
18+
# Sensitive or high-churn CLion files
19+
.idea/**/dataSources/
20+
.idea/**/dataSources.ids
21+
.idea/**/dataSources.local.xml
22+
.idea/**/sqlDataSources.xml
23+
.idea/**/dynamic.xml
24+
.idea/**/uiDesigner.xml
25+
.idea/**/dbnavigator.xml
26+
27+
# Gradle
28+
.idea/**/gradle.xml
29+
.idea/**/libraries
30+
31+
# VS Code build dir
32+
build/
33+
34+
# VS Code config files
35+
.vscode/
36+
37+
# Python stuff
38+
*.pyc
39+
40+
# Mac stuff
41+
.DS_Store

.gitmodules

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[submodule "mbed-os"]
2+
path = mbed-os
3+
url = https://github.com/mbed-ce/mbed-os.git
4+
[submodule "mcuboot"]
5+
path = mcuboot
6+
url = https://github.com/multiplemonomials/mcuboot.git

CMakeLists.txt

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,41 @@
1-
# Copyright (c) 2021 ARM Limited. All rights reserved.
2-
# SPDX-License-Identifier: Apache-2.0
1+
cmake_minimum_required(VERSION 3.19)
2+
cmake_policy(VERSION 3.19)
33

4-
# Mbed-MCUboot Demo Application
4+
set(MBED_APP_JSON_PATH mbed_app.json5)
55

6-
cmake_minimum_required(VERSION 3.19.0 FATAL_ERROR)
6+
include(mbed-os/tools/cmake/app.cmake)
77

8-
set(MBED_PATH ${CMAKE_CURRENT_SOURCE_DIR}/mbed-os CACHE INTERNAL "")
9-
set(MCUBOOT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/mcuboot CACHE INTERNAL "")
10-
set(MBED_CONFIG_PATH ${CMAKE_CURRENT_BINARY_DIR} CACHE INTERNAL "")
11-
set(APP_TARGET application)
8+
# Make sure that the build system generates both bin and hex files, regardless of
9+
# target settings.
10+
set(MBED_OUTPUT_EXT "" CACHE STRING "" FORCE)
1211

13-
include(${MBED_PATH}/tools/cmake/app.cmake)
12+
add_subdirectory(mbed-os)
1413

15-
project(${APP_TARGET})
14+
project(mbed-mcuboot-demo-app)
1615

17-
add_subdirectory(${MBED_PATH})
18-
add_subdirectory(${MCUBOOT_PATH}/boot/bootutil/)
19-
add_subdirectory(${MCUBOOT_PATH}/boot/mbed/) # Mbed-MCUboot Port
16+
# Compile mcuboot sources
17+
add_subdirectory(mcuboot/boot/bootutil)
18+
add_subdirectory(mcuboot/boot/mbed)
2019

21-
add_executable(${APP_TARGET})
20+
add_executable(SimpleApp SimpleApp.cpp secondary_bd.cpp)
21+
target_link_libraries(SimpleApp
22+
mbed-baremetal
23+
mbed-storage
24+
mbed-mcuboot)
25+
mbed_set_post_build(SimpleApp)
2226

23-
target_sources(${APP_TARGET}
24-
PUBLIC
25-
main.cpp
26-
)
27+
add_executable(UpdaterApp UpdaterApp.cpp secondary_bd.cpp)
28+
target_link_libraries(UpdaterApp
29+
mbed-os
30+
mbed-storage
31+
mbed-mcuboot)
32+
mbed_set_post_build(UpdaterApp)
2733

28-
target_link_libraries(${APP_TARGET}
29-
PUBLIC
30-
bootutil
31-
mbed-mcuboot
32-
mbed-storage
33-
mbed-os
34-
)
34+
# Time for a bit of CMake magic: we take the bin file for SimpleApp, then link it into
35+
# UpdaterApp as block of constant data. The name in code is based on the filename passed
36+
# here to the linker.
37+
# See here for more details on this: https://gareus.org/wiki/embedding_resources_in_executables
38+
target_link_options(UpdaterApp PRIVATE -Wl,-b,binary,$<TARGET_FILE_BASE_NAME:SimpleApp>.bin -Wl,-b,elf32-littlearm)
39+
add_dependencies(UpdaterApp SimpleApp) # Ensure SimpleApp gets built before UpdaterApp
3540

36-
mbed_set_post_build(${APP_TARGET})
37-
38-
option(VERBOSE_BUILD "Have a verbose build process")
39-
if(VERBOSE_BUILD)
40-
set(CMAKE_VERBOSE_MAKEFILE ON)
41-
endif()
41+
mbed_finalize_build()

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
This example project shows how to configure an Mbed-OS application to be booted by an mcuboot bootloader.
44

5-
All information for this example has been moved to the combined README in the bootloader repository, [`mbed-mcuboot-demo`](https://github.com/AGlass0fMilk/mbed-mcuboot-demo).
5+
All information for this example has been moved to the combined README in the bootloader repository, [`mbed-mcuboot-bootloader`](https://github.com/mbed-ce/mbed-mcuboot-bootloader).
66

77
### License and contributions
88

SimpleApp.cpp

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
/*
2+
* Copyright (c) 2024 Jamie Smith
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* The Simple App is an application which simply has the ability to set the
6+
* update complete flag, and otherwise just blinks the LED and prints messages.
7+
*/
8+
9+
#include "mbed.h"
10+
#include "mbed-trace/mbed_trace.h"
11+
12+
#include "bootutil/bootutil.h"
13+
14+
#define TRACE_GROUP "SimpleApp"
15+
16+
#if DEMO_BUTTON_ACTIVE_LOW
17+
#define DEMO_BUTTON_IS_PRESSED !btn
18+
#else
19+
#define DEMO_BUTTON_IS_PRESSED btn
20+
#endif
21+
22+
int main()
23+
{
24+
// Enable traces from relevant trace groups
25+
mbed_trace_init();
26+
mbed_trace_include_filters_set("SimpleApp,MCUb,BL");
27+
28+
DigitalIn btn(DEMO_BUTTON);
29+
DigitalOut led(LED1);
30+
31+
// Check if an update has been performed
32+
int swap_type = boot_swap_type();
33+
int ret;
34+
switch (swap_type)
35+
{
36+
case BOOT_SWAP_TYPE_NONE:
37+
tr_info("Regular boot");
38+
break;
39+
40+
case BOOT_SWAP_TYPE_REVERT:
41+
// After MCUboot has swapped a (non-permanent) update image
42+
// into the primary slot, it defaults to reverting the image on the NEXT boot.
43+
// This is why we see "[INFO][MCUb]: Swap type: revert" which can be misleading.
44+
// Confirming the CURRENT boot dismisses the reverting.
45+
tr_info("Firmware update applied successfully");
46+
47+
// Do whatever is needed to verify the firmware is okay (eg: self test)
48+
// then mark the update as successful. Here we let the user press a button.
49+
tr_info("Press the button to confirm, or reboot to revert the update");
50+
51+
while (DEMO_BUTTON_IS_PRESSED)
52+
{
53+
ThisThread::sleep_for(10ms);
54+
}
55+
56+
ret = boot_set_confirmed();
57+
if (ret == 0)
58+
{
59+
tr_info("Current firmware set as confirmed");
60+
return 0;
61+
}
62+
else
63+
{
64+
tr_error("Failed to confirm the firmware: %d", ret);
65+
}
66+
break;
67+
68+
// Note: Below are intermediate states of MCUboot and
69+
// should never reach the application...
70+
case BOOT_SWAP_TYPE_FAIL: // Unable to boot due to invalid image
71+
case BOOT_SWAP_TYPE_PERM: // Permanent update requested (when signing the image) and to be performed
72+
case BOOT_SWAP_TYPE_TEST: // Revertable update requested and to be performed
73+
case BOOT_SWAP_TYPE_PANIC: // Unrecoverable error
74+
default:
75+
tr_error("Unexpected swap type: %d", swap_type);
76+
}
77+
78+
while(true)
79+
{
80+
ThisThread::sleep_for(1s);
81+
printf("Simple app is running...\n");
82+
led = 1;
83+
ThisThread::sleep_for(250ms);
84+
led = 0;
85+
ThisThread::sleep_for(250ms);
86+
led = 1;
87+
ThisThread::sleep_for(250ms);
88+
led = 0;
89+
}
90+
}

UpdaterApp.cpp

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* Copyright (c) 2020 Embedded Planet
3+
* Copyright (c) 2020 ARM Limited
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include "mbed.h"
8+
9+
#include "bootutil/bootutil.h"
10+
#include "bootutil/image.h"
11+
#include "flash_map_backend/secondary_bd.h"
12+
13+
#include "FlashIAP/FlashIAPBlockDevice.h"
14+
#include "blockdevice/BufferedBlockDevice.h"
15+
#include "drivers/InterruptIn.h"
16+
17+
#define TRACE_GROUP "UpdaterApp"
18+
#include "mbed-trace/mbed_trace.h"
19+
20+
#if DEMO_BUTTON_ACTIVE_LOW
21+
#define DEMO_BUTTON_IS_PRESSED !btn
22+
#else
23+
#define DEMO_BUTTON_IS_PRESSED btn
24+
#endif
25+
26+
// SimpleApp.bin gets loaded into ram between these addresses.
27+
// See CMakeLists.txt for details on how this is done.
28+
extern "C" uint8_t _binary_SimpleApp_bin_start;
29+
extern "C" uint8_t _binary_SimpleApp_bin_end;
30+
const size_t SimpleApp_bin_length = &_binary_SimpleApp_bin_end - &_binary_SimpleApp_bin_start;
31+
32+
int main()
33+
{
34+
// Enable traces from relevant trace groups
35+
mbed_trace_init();
36+
mbed_trace_include_filters_set("UpdaterApp,MCUb,BL");
37+
38+
DigitalIn btn(DEMO_BUTTON);
39+
40+
// Erase secondary slot
41+
// On the first boot, the secondary BlockDevice needs to be clean
42+
// If the first boot is not normal, please run the erase step, then reboot
43+
44+
tr_info("> Press button to erase secondary slot");
45+
46+
while(!DEMO_BUTTON_IS_PRESSED) {
47+
ThisThread::sleep_for(10ms);
48+
}
49+
50+
BlockDevice *secondary_bd = get_secondary_bd();
51+
int ret = secondary_bd->init();
52+
if (ret == 0) {
53+
tr_info("Secondary BlockDevice inited");
54+
} else {
55+
tr_error("Cannot init secondary BlockDevice: %d", ret);
56+
}
57+
58+
// Use a buffered block device to allow arbitrary length writes to the underlying BD
59+
BufferedBlockDevice bufferedSecBD(secondary_bd);
60+
61+
tr_info("Erasing secondary BlockDevice...");
62+
ret = bufferedSecBD.erase(0, bufferedSecBD.size());
63+
if (ret == 0) {
64+
tr_info("Secondary BlockDevice erased");
65+
} else {
66+
tr_error("Cannot erase secondary BlockDevice: %d", ret);
67+
}
68+
69+
tr_info("> Press button to copy update image to secondary BlockDevice");
70+
71+
while(!DEMO_BUTTON_IS_PRESSED) {
72+
ThisThread::sleep_for(10ms);
73+
}
74+
75+
// Copy the update image from internal flash to secondary BlockDevice
76+
bufferedSecBD.program(&_binary_SimpleApp_bin_start, 0, SimpleApp_bin_length);
77+
78+
// Activate the image in the secondary BlockDevice
79+
tr_info("> Image copied to secondary BlockDevice, press button to activate");
80+
81+
while(!DEMO_BUTTON_IS_PRESSED) {
82+
ThisThread::sleep_for(10ms);
83+
}
84+
85+
ret = boot_set_pending(false);
86+
if (ret == 0) {
87+
tr_info("> Secondary image pending, reboot to update");
88+
} else {
89+
tr_error("Failed to set secondary image pending: %d", ret);
90+
}
91+
}

0 commit comments

Comments
 (0)