Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.vscode/

build*/
mcuboot/
29 changes: 29 additions & 0 deletions boards/overlays/nucleo_g431rb.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
&flash0 {
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;

boot_partition: partition@0 {
label = "mcuboot";
reg = <0x00000000 0x00020000>; /* 128KB */
read-only;
};

slot0_partition: partition@20000 {
label = "image-0";
reg = <0x00020000 0x00060000>; /* 384KB */
};

slot1_partition: partition@80000 {
label = "image-1";
reg = <0x00080000 0x00060000>; /* 384KB */
};
};
};

/ {
chosen {
zephyr,code-partition = &boot_partition;
};
};
8 changes: 8 additions & 0 deletions drivers/bootloader/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.20.0)

set(MCUBOOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../../bootloader/mcuboot/boot/zephyr)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(mcuboot_bootloader)

add_subdirectory(${MCUBOOT_DIR} mcuboot)
36 changes: 36 additions & 0 deletions drivers/bootloader/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
CONFIG_SIZE_OPTIMIZATIONS=y

# Size required - inside /bootloader/mcuboot/boot/zephyr/prj.conf
# CONFIG_MAIN_STACK_SIZE=10240

# min tested stack size that works with/without debugging
CONFIG_MAIN_STACK_SIZE=2048

# Signature of bootloader
CONFIG_BOOT_SIGNATURE_TYPE_ECDSA_P256=y
CONFIG_BOOT_SIGNATURE_KEY_FILE="root-ec-p256.pem"

# Flash support
CONFIG_FLASH=y

# Boot mode
CONFIG_BOOT_SWAP_USING_MOVE=y

# Reduce features to fit in 12KB
CONFIG_BOOT_BOOTSTRAP=n
CONFIG_MCUBOOT_SERIAL=n

# Disable for debugging
# CONFIG_GPIO=n
# CONFIG_CONSOLE=n
# CONFIG_UART_CONSOLE=n
# CONFIG_SERIAL=n
# CONFIG_LOG=n

# Enable for debugging
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
CONFIG_SERIAL=y
CONFIG_LOG=y
CONFIG_LOG_MODE_MINIMAL=y
CONFIG_BOOT_BANNER=y
9 changes: 9 additions & 0 deletions drivers/mcuboot_demo/image1/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2025 The FINCH CubeSat Project Flight Software Contributors
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(obc)

target_sources(app PRIVATE src/blinky1.c)
# target_sources(app PRIVATE src/blinky2.c)
29 changes: 29 additions & 0 deletions drivers/mcuboot_demo/image1/app.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
&flash0 {
partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;

boot_partition: partition@0 {
label = "mcuboot";
reg = <0x00000000 0x00020000>; /* 128KB */
read-only;
};

slot0_partition: partition@20000 {
label = "image-0";
reg = <0x00020000 0x00060000>; /* 384KB */
};

slot1_partition: partition@80000 {
label = "image-1";
reg = <0x00080000 0x00060000>; /* 384KB */
};
};
};

/ {
chosen {
zephyr,code-partition = &boot_partition;
};
};
27 changes: 27 additions & 0 deletions drivers/mcuboot_demo/image1/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Enable STREAM_FLASH first (required dependency for IMG_MANAGER)
CONFIG_STREAM_FLASH=y

# Enable IMG_MANAGER (parent config)
CONFIG_IMG_MANAGER=y

# Then enable MCUboot variant (this is selected automatically as default, but be explicit)
CONFIG_MCUBOOT_IMG_MANAGER=y

# Required dependencies
CONFIG_BOOTLOADER_MCUBOOT=y
CONFIG_FLASH=y
CONFIG_FLASH_MAP=y

# Reboot support
CONFIG_REBOOT=y

# Signature types: none, rsa, ecdsa
# CONFIG_MCUBOOT_GENERATE_UNSIGNED_IMAGE=y
# CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="/bootloader/mcuboot/root-rsa-2048.pem"
CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="/bootloader/mcuboot/root-ec-p256.pem"

# Logging (optional)
CONFIG_LOG=y
CONFIG_PRINTK=y
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
57 changes: 57 additions & 0 deletions drivers/mcuboot_demo/image1/src/blinky1.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/* Copyright (c) 2025 The FINCH CubeSat Project Flight Software Contributors*/
/* SPDX-License-Identifier: Apache-2.0 */

#include <zephyr/kernel.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/dfu/mcuboot.h>
#include <zephyr/sys/reboot.h>

#define LED_NODE DT_ALIAS(led0)
static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET_OR(LED_NODE, gpios, {0});

void main(void)
{
// 1. Initialization
// If this image just booted successfully, mark it as "Good" so we don't revert.
if (!boot_is_img_confirmed()) {
printk("Confirming image...\n");
boot_write_img_confirmed();
}

gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);

printk("Running FAST blinky (Image 1).\n");
printk("System will auto-swap in approx 10 seconds...\n");

int blink_count = 0;
int trigger_threshold = 50; // 50 * 200ms = 10 seconds

// 2. The Main Loop
while (1) {
gpio_pin_toggle_dt(&led);
k_msleep(200); // Fast blink

blink_count++;

// 3. The Automatic Trigger Check
if (blink_count == trigger_threshold) {
printk("Time's up! Requesting upgrade to slow blinky...\n");

// A. Request the swap (Test Mode)
// 'BOOT_UPGRADE_TEST' ensures that if the new image crashes,
// the bootloader will swap BACK to this one automatically.
int ret = boot_request_upgrade(BOOT_UPGRADE_TEST);

if (ret == 0) {
printk("Upgrade requested successfully. Rebooting now!\n");
// Give the serial port a moment to flush the text
k_msleep(100);

// B. Software Reset (Simulates the Black Button)
sys_reboot(SYS_REBOOT_COLD);
} else {
printk("Failed to request upgrade: %d\n", ret);
}
}
}
}
9 changes: 9 additions & 0 deletions drivers/mcuboot_demo/image2/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2025 The FINCH CubeSat Project Flight Software Contributors
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(obc)

# target_sources(app PRIVATE src/blinky1.c)
target_sources(app PRIVATE src/blinky2.c)
27 changes: 27 additions & 0 deletions drivers/mcuboot_demo/image2/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Enable STREAM_FLASH first (required dependency for IMG_MANAGER)
CONFIG_STREAM_FLASH=y

# Enable IMG_MANAGER (parent config)
CONFIG_IMG_MANAGER=y

# Then enable MCUboot variant (this is selected automatically as default, but be explicit)
CONFIG_MCUBOOT_IMG_MANAGER=y

# Required dependencies
CONFIG_BOOTLOADER_MCUBOOT=y
CONFIG_FLASH=y
CONFIG_FLASH_MAP=y

# Reboot support
CONFIG_REBOOT=y

# Signature types: none, rsa, ecdsa
# CONFIG_MCUBOOT_GENERATE_UNSIGNED_IMAGE=y
# CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="/bootloader/mcuboot/root-rsa-2048.pem"
CONFIG_MCUBOOT_SIGNATURE_KEY_FILE="/bootloader/mcuboot/root-ec-p256.pem"

# Logging (optional)
CONFIG_LOG=y
CONFIG_PRINTK=y
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
51 changes: 51 additions & 0 deletions drivers/mcuboot_demo/image2/src/blinky2.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/* Copyright (c) 2025 The FINCH CubeSat Project Flight Software Contributors*/
/* SPDX-License-Identifier: Apache-2.0 */

#include <zephyr/sys/reboot.h>

#define LED_NODE DT_ALIAS(led0)
#define SW0_NODE DT_ALIAS(sw0)

static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET_OR(LED_NODE, gpios, {0});
static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET_OR(SW0_NODE, gpios, {0});
static struct gpio_callback button_cb;

void button_pressed(const struct device *dev, struct gpio_callback *cb, uint32_t pins)
{
printk("Button pressed! Requesting upgrade to fast blinky...\n");

int ret = boot_request_upgrade(BOOT_UPGRADE_TEST);
if (ret) {
printk("Failed to request upgrade: %d\n", ret);
return;
}

printk("Upgrade requested, rebooting in next reset...\n");

// could command a system reboot on button press or hold off until next reset

// k_msleep(100);
// sys_reboot(SYS_REBOOT_COLD);
}

void main(void)
{
if (!boot_is_img_confirmed()) {
printk("Confirming image...\n");
boot_write_img_confirmed();
}

gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE);

gpio_pin_configure_dt(&button, GPIO_INPUT);
gpio_pin_interrupt_configure_dt(&button, GPIO_INT_EDGE_TO_ACTIVE);
gpio_init_callback(&button_cb, button_pressed, BIT(button.pin));
gpio_add_callback(button.port, &button_cb);

printk("Running slow blinky. Press button to swap.\n");

while (1) {
gpio_pin_toggle_dt(&led);
k_msleep(1000); // Slow blink: 1 sec
}
}
13 changes: 13 additions & 0 deletions scripts/build_mcu.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash

Check failure on line 1 in scripts/build_mcu.sh

View workflow job for this annotation

GitHub Actions / Copyright Check

missing copyright

west build -p always -b nucleo_g431rb -d build_mcuboot /bootloader/mcuboot/boot/zephyr -- \
-DCONF_FILE=/workspace/drivers/bootloader/prj.conf

# blinky1.c in mcuboot_demo CMake
west build -p always -b nucleo_g431rb -d build_fast drivers/mcuboot_demo/image1

# blinky2.c in mcuboot_demo CMake
west build -p always -b nucleo_g431rb -d build_slow drivers/mcuboot_demo/image2

# build own key for production - key used for signing images
# python3 /bootloader/mcuboot/scripts/imgtool.py keygen -k production-key-ec-p256.pem -t ecdsa-p256
16 changes: 16 additions & 0 deletions scripts/flash_mcuboot.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash

Check failure on line 1 in scripts/flash_mcuboot.sh

View workflow job for this annotation

GitHub Actions / Copyright Check

missing copyright

set -e

echo "=== Flashing MCUboot Setup ==="

echo "1. Flashing MCUboot bootloader..."
pyocd flash -t stm32g431rbtx build_mcuboot/zephyr/zephyr.hex

echo "2. Flashing fast_blinky to slot 0 (0x08008800)..."
pyocd flash -t stm32g431rbtx --base-address 0x08008800 build_fast/zephyr/zephyr.signed.bin

echo "3. Flashing slow_blinky to slot 1 (0x08014800)..."
pyocd flash -t stm32g431rbtx --base-address 0x08014800 build_slow/zephyr/zephyr.signed.bin

echo "=== Done! Reset board to boot ==="
4 changes: 4 additions & 0 deletions west.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ manifest:
url: https://github.com/libcsp/libcsp.git
revision: f8c366e5dfd9879990747d815ff5b2c2dda4dfe3
path: modules/lib/libcsp
- name: mcuboot
url: https://github.com/mcu-tools/mcuboot
revision: v2.1.0
path: bootloader/mcuboot
Loading