Skip to content

Commit

Permalink
doc: SUIT recovery button documentation
Browse files Browse the repository at this point in the history
This commit documents the feature allowing to enter
SUIT recovery via a button press.

Signed-off-by: Artur Hadasz <[email protected]>
  • Loading branch information
ahasztag committed Dec 5, 2024
1 parent 5983a0c commit 1ff5cd7
Showing 1 changed file with 175 additions and 1 deletion.
176 changes: 175 additions & 1 deletion doc/nrf/app_dev/device_guides/nrf54h/ug_nrf54h20_suit_recovery.rst
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ These issues can occur in the following scenarios:
If any bugs are overlooked during the development phase, this could result in inconsistencies in the firmware.

Recovery Mode and Recovery Manifests
*************************************************
************************************

The recovery manifests form a separate hierarchy from the normal manifests.
In this hierarchy, the application recovery (``APP_RECOVERY``) manifest is responsible for managing both the application core image and other manifests, such as the radio recovery manifest.
Expand Down Expand Up @@ -236,3 +236,177 @@ To turn an application into a recovery application, the following steps have to
The value of ``SUIT_RECOVERY_APPLICATION_PATH`` can contain variables like ``${ZEPHYR_NRF_MODULE_DIR}``

#. When building the main application, set ``SB_CONFIG_SUIT_RECOVERY_APPLICATION_CUSTOM`` (or the Kconfig option name if a different one was chosen) to ``y``.

.. _ug_nrf54h20_suit_recovery_enter_recovery_request:

Entering recovery via are a request from the local domains
**********************************************************

It is possible to enter recovery mode via a request sent from the local domains.
This can be used for several purposes, such as:

* Recovering the device if the main firmware crashes and no JLink connection is available.
* Using the recovery application as a "foreground update" application, allowing to save some space in the main application.
* Debugging the recovery application.

:ref:`<ug_nrf54h20_suit_recovery_enter_via_button>` uses such requests.
The code for this feature is located in the :file:`nrf/subsys/suit/app_tools/recovery_button` directory.
It can be used as a reference design.

To request entering the recovery mode, the ``suit_foreground_dfu_required()`` function must be called.

To exit recovery mode, the ``suit_boot_flags_reset()`` must be called from the recovery application.
However - if the main application firmware is corrupted, the device will regardlessly enter recovery mode again on the next boot.

"Enter recovery check" by running recovery firmware (companion image) before the main application
=================================================================================================

In some cases the device might need to check if the it should enter recovery mode before running the main application.
For example, the developer might want to enter recovery mode if a button is pressed during boot.

This can be done by running the recovery application as a companion image before the main application in the invoke path.
A different companion might be used for this purpose, but the recovery application is the most common choice.
It allows reusing the recovery firmware for multiple purposes, simplifying the system.

The recovery (companion) application can check if the device should enter recovery mode and set the recovery flag using ``suit_foreground_dfu_required()`` if needed.
It is important to only do this if the device is currently in the SUIT_BOOT_MODE_INVOKE boot mode - the current boot mode can be checked using ``suit_boot_mode_read``.
If the device should remain in normal boot mode (the condidion is not met) or the device already is in recovery mode, the firmware should call ``suit_invoke_confirm(0)``.
This will allow for further proccessing of the SUIT manifest by the Secure Domain Frimware and booting the main application.

To enable this feature, the following steps must be performed.
This is assuming that the companion image is orchestrated by the APP_LOCAL_3 SUIT manifest - which will be true by default when using the recovery firmware as the companion.

1. Add the appropriate checking code the recovery (companion) application in its startup code.
The following code snippet can be used:

..code-block:: c

static int should_enter_recovery_check(void)
{
suit_boot_mode_t mode = SUIT_BOOT_MODE_INVOKE_RECOVERY;
suit_ssf_err_t err = SUIT_PLAT_SUCCESS;
int ret = 0;

err = suit_boot_mode_read(&mode);

if (err != SUIT_PLAT_SUCCESS) {
suit_invoke_confirm(-EPIPE);
return -EPIPE;
}

if (mode == SUIT_BOOT_MODE_INVOKE) {
if (/* add the condition here */) {
err = suit_foreground_dfu_required();
}
}
if (err != SUIT_PLAT_SUCCESS) {
ret = -EPIPE;
}

(void)suit_invoke_confirm(ret);

return ret;
}

SYS_INIT(should_enter_recovery_check, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);

The code should be placed in the recovery (companion) application's source code.
To do this, create a module with this code and attach it to the Nordic provided recovery application or create a custom recovery application/companion image.

2. If using the default SUIT manifests and running the recovery image as the companion image, no modifications to the manifest templates are needed.
Instead, set the :kconfig:option:`CONFIG_SUIT_INVOKE_APP_LOCAL_3_BEFORE_MAIN_APP` option in the recovery image.
This can be done by adding ``-Drecovery_CONFIG_SUIT_INVOKE_APP_LOCAL_3_BEFORE_MAIN_APP=y`` to the build command when building the recovery application.

However, otherwise, the manifest templates have to be modified as follows:

a. In the APP_LOCAL_3 manifest template, add the following code before the ``suit-directive-invoke`` directive on the companion image:

.. code-block:: yaml
- suit-directive-override-parameters:
suit-parameter-invoke-args:
suit-synchronous-invoke: True
suit-timeout: 1000
b. In the root manifest template add the ``INSTLD_MFST`` component for the local manifest orchestrating the comapanion image.
Make sure it is invoked before the main application images.
If the modified template is based on the root manifest template from |NCS|, it will in most cases be enough to add it as the first manifst in the component list.
The following code snippet is responsible for this in the default root manifest template:

.. code-block:: yaml
{{- component_list.append( app_recovery_local_component_index ) or ""}}
- - INSTLD_MFST
- RFC4122_UUID:
namespace: {{ mpi_app_recovery_local_vendor_name }}
name: {{ mpi_app_recovery_local_class_name }}
.. _ug_nrf54h20_suit_recovery_enter_via_button:

Entering recovery via button press
==================================

A common use case for entering recovery mode is to allow the device to enter recovery mode by pressing a button.
In NCS this use case is provided as a simple plug-and-play solution.
When it is enabled, the device will enter recovery mode if the button is pressed during boot.

.. note::
If no modifications or additional modules are added to the recovery application the only way to exit the recovery mode is performing a device firmware upgrade.

There are two variants of this feature:

* Recovery button checked in the recovery application run as a companion image at boot stage (recommended).
* Recovery button checked in the main application.

The first variant is recommended as it allows to perform the check independently of the main application.

Recovery button checked in the recovery application
---------------------------------------------------

In this variant,the recovery application is run as a companion image before the main application as part of the normal invoke path.
It checks if the device already is in recovery mode.
If it is, the recovery application proceeds with its normal operation allowing to recover firmware.

If the device is not in recovery mode, the recovery application checks if the specified button is pressed.
If the button is pressed, the recovery application sets the recovery flag and reboots the device.
Otherwise it sends a confirmation message to the Secure Domain Firmware, which then halts the recovery application and proceeds with booting the main application.

To enable the feature add the following code to :file:`sysbuild/recovery.overlay` in the main application directory:

.. code-block:: dts
/ {
chosen {
ncs,recovery-button = &button0;
};
};
Replace ``button0`` with the appropriate button node.


.. note::
In this option running the recovery application as a companion image is orchestrated by the root SUIT manifest.
Special care must be taken if the root manifest template is modified.
If incorrect modifications are made to the root manifest, the button press feature might not work.
This might lead to the device being unrecoverable without a JLink connection in case of a crash.


Recovery button checked in the main application
-----------------------------------------------

In this variant a check if the specified button is pressed is performed at an early stage when inside the main application firmware.
If the button is pressed, the recovery flag is set and the device reboots.

To enable the feature in this variant add the following overlay to the main application's configuration:

.. code-block:: dts
/ {
chosen {
ncs,recovery-button = &button0;
};
};
Replace ``button0`` with the appropriate button node.

0 comments on commit 1ff5cd7

Please sign in to comment.