Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,11 @@ For more information on the boot sequence, see :ref:`ug_nrf54h20_architecture_bo
The term "secondary slot" and "secondary image" are used in the MCUboot context.
This usage is unrelated to the "secondary firmware" described in this section.

Sample
======

For an example of how to create a secondary image with automatic triggers, see the :ref:`secondary_boot_trigger_lockup_sample` sample.

.. _ug_nrf54h20_ironside_se_secondary_conf_trigger:

Configuration and triggering
Expand Down
1 change: 0 additions & 1 deletion samples/ironside_se/secondary_boot_gen_uicr/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ After programming the test to your development kit, complete the following steps
#. Reset the kit.
#. Observe the console output for both cores:


.. code-block:: console

[00:00:00.123,456] === Hello World from Primary Image ===
Expand Down
2 changes: 1 addition & 1 deletion samples/ironside_se/secondary_boot_gen_uicr/sample.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ tests:
samples.secondary_boot.nrf54h20dk:
tags:
- sysbuild
- ci_samples_secondary_boot
- ci_samples_sdfw
platform_allow:
- nrf54h20dk/nrf54h20/cpuapp
integration_platforms:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Copyright (c) 2025 Nordic Semiconductor ASA
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause

cmake_minimum_required(VERSION 3.20.0)

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

# Source files
target_sources(app PRIVATE src/main.c)
109 changes: 109 additions & 0 deletions samples/ironside_se/secondary_boot_trigger_lockup/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
.. _secondary_boot_trigger_lockup_sample:

Secondary boot with APPLICATIONLOCKUP trigger
##############################################

.. contents::
:local:
:depth: 2

This sample demonstrates an automatic secondary boot triggered by a lockup of the application core CPU on the nRF54H20 DK.
When the primary application triggers a CPU lockup, IronSide SE automatically boots the secondary image without requiring any application-level software intervention.

Requirements
************

The sample supports the following development kit:

.. table-from-sample-yaml::

Overview
********

The sample consists of two applications:

* *Primary Image*: Runs initially on the application core (``cpuapp``), prints status messages, and deliberately triggers a CPU lockup by disabling fault exceptions and then causing a fault.
* *Secondary Image*: Automatically boots after the lockup is detected and runs continuously.

The UICR.SECONDARY.TRIGGER.APPLICATIONLOCKUP configuration causes IronSide SE to automatically boot the secondary image when a CPU lockup is detected.

Configuration
*************

The sample uses the following UICR configuration in the :file:`sysbuild/uicr.conf` file:

.. code-block:: kconfig

CONFIG_GEN_UICR_SECONDARY=y
CONFIG_GEN_UICR_SECONDARY_TRIGGER=y
CONFIG_GEN_UICR_SECONDARY_TRIGGER_APPLICATIONLOCKUP=y

This enables automatic secondary boot when the application core experiences a CPU lockup.

For more information about secondary firmware configuration and other available triggers, see :ref:`ug_nrf54h20_ironside_se_secondary_firmware`.

Building and running
********************

.. |sample path| replace:: :file:`samples/ironside_se/secondary_boot_trigger_lockup`

.. include:: /includes/build_and_run_ns.txt

To build the sample for the nRF54H20 DK, run the following command:

.. code-block:: console

west build -b nrf54h20dk/nrf54h20/cpuapp samples/ironside_se/secondary_boot_trigger_lockup

To program the sample on the device, run the following command:

.. code-block:: console

west flash

Testing
*******

After programming the sample to your development kit, complete the following steps to test it:

1. |connect_terminal|
#. Reset the kit.
#. Observe in the console output the primary image startup and lockup trigger:

.. code-block:: console

=== Primary Image: Demonstrating APPLICATIONLOCKUP trigger ===
This image will intentionally trigger a CPU lockup.
The UICR.SECONDARY.TRIGGER.APPLICATIONLOCKUP configuration will
automatically boot the secondary image.

Triggering CPU lockup now!
Step 1: Disabling fault exceptions and then accessing invalid memory...

#. Observe in the console output that the system automatically reboots into the secondary image:

.. code-block:: console

=== Secondary Image: Successfully booted! ===
The system automatically booted the secondary image due to
APPLICATION LOCKUP in the primary image.

This demonstrates UICR.SECONDARY.TRIGGER.APPLICATIONLOCKUP
automatic failover capability.

Secondary image heartbeat - system is stable
Secondary image heartbeat - system is stable
...

Dependencies
************

This sample uses the following |NCS| subsystems:

* Sysbuild - Enables building multiple images in a single build process
* UICR generation - Configures the User Information Configuration Registers for automatic secondary boot on lockup

In addition, it uses the following Zephyr subsystems:

* :ref:`Kernel <kernel>` - Provides basic system functionality and threading
* :ref:`Console <console>` - Enables UART console output for debugging and user interaction
7 changes: 7 additions & 0 deletions samples/ironside_se/secondary_boot_trigger_lockup/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#
# Copyright (c) 2025 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

# This file is intentionally left empty
26 changes: 26 additions & 0 deletions samples/ironside_se/secondary_boot_trigger_lockup/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
sample:
name: Secondary Boot APPLICATIONLOCKUP Trigger Sample
description: |
Sample demonstrating automatic secondary boot triggered by APPLICATIONLOCKUP
on nRF54H20DK. The primary image deliberately triggers a CPU lockup, and the
UICR.SECONDARY.TRIGGER.APPLICATIONLOCKUP configuration causes IronSide SE to
automatically boot the secondary image.

common:
sysbuild: true
harness: console
harness_config:
type: multi_line
regex:
- "=== Primary Image: Demonstrating APPLICATIONLOCKUP trigger ==="
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it needed specific order of the lines?

- "=== Secondary Image: Successfully booted! ==="

tests:
samples.secondary_boot_trigger_lockup.nrf54h20dk:
tags:
- sysbuild
- ci_samples_sdfw
platform_allow:
- nrf54h20dk/nrf54h20/cpuapp
integration_platforms:
- nrf54h20dk/nrf54h20/cpuapp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Copyright (c) 2025 Nordic Semiconductor ASA
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause

cmake_minimum_required(VERSION 3.20.0)

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

target_sources(app PRIVATE src/main.c)
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

/ {
chosen {
zephyr,code-partition = &secondary_partition;
};
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#
# Copyright (c) 2025 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

CONFIG_IS_IRONSIDE_SE_SECONDARY_IMAGE=y

# Use the devicetree chosen code-partition to determine flash load offset
CONFIG_USE_DT_CODE_PARTITION=y

# NB: app.overlay sets zephyr,code-partition to secondary_partition
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA.
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>

int main(void)
{
printk("\n=== Secondary Image: Successfully booted! ===\n");
printk("The system automatically booted the secondary image due to\n");
printk("APPLICATION LOCKUP in the primary image.\n");
printk("\nThis demonstrates UICR.SECONDARY.TRIGGER.APPLICATIONLOCKUP\n");
printk("automatic failover capability.\n");

/* Secondary firmware runs continuously */
while (1) {
k_msleep(5000);
printk("Secondary image heartbeat - system is stable\n");
}

return 0;
}
32 changes: 32 additions & 0 deletions samples/ironside_se/secondary_boot_trigger_lockup/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2025 Nordic Semiconductor ASA.
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>

int main(void)
{
printk("=== Primary Image: Demonstrating APPLICATIONLOCKUP trigger ===\n");
printk("This image will intentionally trigger a CPU lockup.\n");
printk("The UICR.SECONDARY.TRIGGER.APPLICATIONLOCKUP configuration will\n");
printk("automatically boot the secondary image.\n");
printk("\nTriggering CPU lockup now!\n");
printk("Step 1: Disabling fault exceptions and then accessing invalid memory...\n");

/* Set FAULTMASK to disable all exceptions except NMI.
* Then trigger a fault - since faults are disabled, this causes lockup.
* Any fault (unaligned access, invalid memory, etc.) will trigger lockup.
*/
__asm volatile("cpsid f" ::: "memory");

/* Trigger fault by accessing invalid memory */
*(volatile uint32_t *)0xFFFFFFFF = 0xDEADBEEF;

/* This line will never be reached */
printk("ERROR: Should have triggered lockup!\n");

return 0;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Copyright (c) 2025 Nordic Semiconductor ASA
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause

ExternalZephyrProject_Add(
APPLICATION secondary
SOURCE_DIR ${APP_DIR}/secondary
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Copyright (c) 2025 Nordic Semiconductor ASA
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause

# Configuration overlay for uicr image
# Enable UICR.SECONDARY with automatic trigger on APPLICATIONLOCKUP
CONFIG_GEN_UICR_SECONDARY=y
CONFIG_GEN_UICR_SECONDARY_TRIGGER=y
CONFIG_GEN_UICR_SECONDARY_TRIGGER_APPLICATIONLOCKUP=y
2 changes: 1 addition & 1 deletion scripts/ci/tags.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1504,7 +1504,7 @@ ci_samples_sdfw:
- modules/hal/nordic/nrfs/
- modules/hal/nordic/nrfx/
- modules/lib/zcbor/
- nrf/samples/sdfw/
- nrf/samples/ironside_se/
- nrf/subsys/nrf_rpc/
- nrf/subsys/sdfw_services/
- nrfxlib/nrf_rpc/
Expand Down
2 changes: 1 addition & 1 deletion west.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ manifest:
# https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/guides/modules.html
- name: zephyr
repo-path: sdk-zephyr
revision: dc45b2a09c7872f52b2ddb00c20bd02eb547a8ae
revision: 5696f6b423a54390721955d6e0e63c363e02cfff
import:
# In addition to the zephyr repository itself, NCS also
# imports the contents of zephyr/west.yml at the above
Expand Down
Loading