Feedback
Feedback

If you are having issues with the exercises, please create a ticket on DevZone: devzone.nordicsemi.com
Click or drag files to this area to upload. You can upload up to 2 files.

Board files for multi-core hardware & TF-M

This topic focuses on learning some core concepts related to defining custom board definitions for the nRF53 and nRF91-based devices.

Special considerations for the nRF91/nRF53 Series

In terms of custom board definitions, a significant difference between the nRF52 Series and the nRF53/nRF91 Series is the type of architecture and CPU they use. The nRF52 Series implements the Armv7-M and has a Cortex-M4 CPU, whereas the nRF53 and nRF91 Series implements the Armv8-M architecture and has a Cortex-M33 CPU with TrustZone, which supports TF-M.

SeriesCPUArchitectureNumber of User Programable CoresTrustZone
nRF52Cortex-M4Armv7-M1No
nRF53Cortex-M33Armv8-M2Yes
nRF91Cortex-M33Armv8-M1Yes

In addition to TF-M, the nRF53 Series is dual-core with two fully programmable cores. This introduces some challenges when defining a custom board, which we will address in this topic and Exercise 2.

Trusted Firmware-M (TF-M)

Trusted Firmware-M (TF-M) is a blueprint for constructing a Secure Processing Environment (SPE) tailored to Arm M-profile architectures. TF-M relies on the principle of security through separation to safeguard sensitive credentials and code. Additionally, TF-M extends its protective capabilities to applications by offering security services, including Protected Storage, Cryptography, and Attestation.

The Nordic Semiconductor nRF53 and nRF91 Series, implementing the Armv8-M architecture (Arm Cortex-M33), incorporate TrustZone technology, which enforces hardware-based segregation between the Secure and Non-secure Processing Environments, effectively creating distinct Trusted and Non-Trusted build images.

This means that we have two options for boards based on the nRF53 and nRF91 Series. Either:

Option 1 – <Board ID>_ns

Enforce security by separation by utilizing TF-M and have our application run in the Non-Secure Processing Environment and have TF-M run in the Secure Processing Environment.

Option 2<Board ID>

Do not enforce security by separation by having our application run as a single image with full access privileges.

Let’s take a board with a board ID <Board ID> as an example:
When building for the <Board ID> , you must build for either <Board ID> or <Board ID>_ns .

  • <Board ID>: The application is built as a single image without security by separation.
  • <Board ID>_ns: The application will be built as a Non-Secure image. Hence, you will get security by separation as TF-M will automatically be built as the Secure image. The two images will be merged to form a combined image that will be used when programming or updating the device.
Option 1 – Security by separation <Board ID>_ns
Option 2 – No security by separation <Board ID>

Working with the nRF53 Series

The nRF5340 is the only System on Chip (SoC) in the nRF53 Series. It is a wireless ultra-low-power multicore SoC with two fully programmable Arm Cortex-M33 processors: a network core and an application core.

See the nRF5340 Product Specification for more information about the nRF5340 SoC

Network core

The network core is an Arm Cortex-M33 processor with a reduced feature set, designed for ultra-low-power operation. Use this core for radio communication and for real-time processing tasks involving low-level radio protocol layers.

In nRF Connect SDK/Zephyr, the firmware of the network core should be built using the following build target:

  • <BoardID>_cpunet

Application core

The application core is a full-featured Arm Cortex-M33 processor including DSP instructions and FPU. Use this core for tasks that require high performance and for application-level logic.

The M33 TrustZone, one of Cortex-M Security Extensions (CMSE), can divide the application MCU into Secure Processing Environment (SPE) and Non-Secure Processing Environment (NSPE). When the MCU boots, it always starts executing from the secure area.

In nRF Connect SDK/Zephyr, the firmware of the application core should be built using one of the following build targets:

  • <BoardID>_cpuapp for build targets with TF-M disabled.
  • <BoardID>_cpuapp_ns for build targets that have TF-M enabled and have the SPE firmware alongside the NSPE firmware.

Working with the nRF91 Series

The nRF91 Series is comprised of four members: nRF9160, nRF9161, nRF9131, and nRF9151 System in Packages (SiP). These are cellular ultra-low-power SiPs with only one fully programmable Arm Cortex-M33 core. The other core is dedicated to the Modem firmware; you can only flash it with a precompiled modem firmware binary.

In nRF Connect SDK/Zephyr, the firmware for the nRF91 SIP should be built using one of the following build targets:

  • <BoardID> for build targets with TF-M disabled.
  • <BoardID>_ns for build targets that have TF-M enabled and have the SPE firmware alongside the NSPE firmware.

Enabling TF-M in board definition

The custom board directory can be a single folder with both build target files (<BoardID> & <BoardID>_ns) in one folder. We will assume a custom board name of “DevAcademy nRF9161”, which we will create in exercise 2.

In the custom board Kconfig files

1. A single Kconfig.board file to define two Kconfig symbols of type Boolean.

Below is a snippet for a custom board named “DevAcademy nRF9161”.

# DevAcademy NRF9161 board configuration

# Copyright (c) 2023 Nordic Semiconductor ASA
# SPDX-License-Identifier: Apache-2.0

if SOC_NRF9161_LACA

config BOARD_DEVACADEMY_NRF9161
	bool "DevAcademy NRF9161"

config BOARD_DEVACADEMY_NRF9161_NS
	bool "DevAcademy NRF9161 non-secure"

endif # SOC_NRF9161_LACA
Kconfig

2. A single Kconfig.defconfig file that should detect the passed build target BOARD_DEVACADEMY_NRF9161_NS or BOARD_DEVACADEMY_NRF9161 .

If BOARD_DEVACADEMY_NRF9161_NS is selected (passed in an application build configuration step or west build), instruct the build system to additionally generate a TF-M image (by enabling BUILD_WITH_TFM), along with the application image. The application image is to be executed in the Non-Secure Processing Environment, and the TF-M image is to be executed in the Secure Execution environment. In addition, the flash and RAM should be adjusted to take TF-M into consideration and generate a merged binary of the two builds (by enabling TFM_FLASH_MERGED_BINARY).

Below is a snippet of a Kconfig.defconfig for the “DevAcademy nRF9161” board.

if BOARD_DEVACADEMY_NRF9161 || BOARD_DEVACADEMY_NRF9161_NS

config BOARD
	default "devacademy_nrf9161"

# By default, if we build for a Non-Secure version of the board,
# enable building with TF-M as the Secure Execution Environment.
config BUILD_WITH_TFM
	default y if BOARD_DEVACADEMY_NRF9161_NS

if BUILD_WITH_TFM

# By default, if we build with TF-M, instruct build system to
# flash the combined TF-M (Secure) & Zephyr (Non Secure) image
config TFM_FLASH_MERGED_BINARY
	bool
	default y

endif # BUILD_WITH_TFM

# For the secure version of the board the firmware is linked at the beginning
# of the flash, or into the code-partition defined in DT if it is intended to
# be loaded by MCUboot. If the secure firmware is to be combined with a non-
# secure image (TRUSTED_EXECUTION_SECURE=y), the secure FW image shall always
# be restricted to the size of its code partition.
# For the non-secure version of the board, the firmware
# must be linked into the code-partition (non-secure) defined in DT, regardless.
# Apply this configuration below by setting the Kconfig symbols used by
# the linker according to the information extracted from DT partitions.

# Workaround for not being able to have commas in macro arguments
DT_CHOSEN_Z_CODE_PARTITION := zephyr,code-partition

config FLASH_LOAD_SIZE
	default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION))
	depends on BOARD_DEVACADEMY_NRF9161 && TRUSTED_EXECUTION_SECURE

if BOARD_DEVACADEMY_NRF9161_NS

config FLASH_LOAD_OFFSET
	default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_CODE_PARTITION))

config FLASH_LOAD_SIZE
	default $(dt_chosen_reg_size_hex,$(DT_CHOSEN_Z_CODE_PARTITION))

endif # BOARD_DEVACADEMY_NRF9161_NS


endif # BOARD_DEVACADEMY_NRF9161 || BOARD_DEVACADEMY_NRF9161_NS

Kconfig

3. Two _defconfig files, basically one for each build target. Therefore, we will have devacademy_nrf9161_ns_defconfig and devacademy_nrf9161_defconfig. In addition to the rules we discussed in Creating board files, we need to do the following.

3.1 In the devacademy_nrf9161_defconfig , we need to enable CONFIG_ARM_TRUSTZONE_M.

# SPDX-License-Identifier: Apache-2.0

CONFIG_SOC_SERIES_NRF91X=y
CONFIG_SOC_NRF9161_LACA=y
CONFIG_BOARD_DEVACADEMY_NRF9161=y

# Enable MPU
CONFIG_ARM_MPU=y

# Enable hardware stack protection
CONFIG_HW_STACK_PROTECTION=y

# Enable TrustZone-M
CONFIG_ARM_TRUSTZONE_M=y

# enable GPIO
CONFIG_GPIO=y

# Enable uart driver
CONFIG_SERIAL=y

# enable console
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y

CONFIG_PINCTRL=y
Kconfig

3.2 In the devacademy_nrf9161_ns_defconfig file , we need to enable both CONFIG_ARM_TRUSTZONE_M to enable TrustZone APIs for the non-secure domain (Application) and also enable CONFIG_TRUSTED_EXECUTION_NONSECURE to imply building Non-Secure firmware. A Non-Secure firmware image will execute in Non-Secure state. Therefore, it shall not access CPU resources (memory areas, peripherals, interrupts etc.) belonging to the Secure domain.

# SPDX-License-Identifier: Apache-2.0

CONFIG_SOC_SERIES_NRF91X=y
CONFIG_SOC_NRF9161_LACA=y
CONFIG_BOARD_DEVACADEMY_NRF9161_NS=y

# Enable MPU
CONFIG_ARM_MPU=y

# Enable hardware stack protection
CONFIG_HW_STACK_PROTECTION=y

# Enable TrustZone-M
CONFIG_ARM_TRUSTZONE_M=y

# This Board implies building Non-Secure firmware
CONFIG_TRUSTED_EXECUTION_NONSECURE=y

# enable GPIO
CONFIG_GPIO=y

# Enable uart driver
CONFIG_SERIAL=y

# enable console
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y

CONFIG_PINCTRL=y
Kconfig

In the custom board Devicetree files

4. Building an application with TF-M, results in building Secure and Non-Secure images. The secure image should be placed in flash0 (or in slot0, if MCUboot bootloader is present). Secure image will use sram0 for system memory.

The Non-Secure image should be placed in slot0_ns, and use sram0_ns for system memory.

Note that the Secure image only requires knowledge of the beginning of the Non-Secure image (not its size).

4.1 Create a partition file for Flash&RAM planning. We could add these directly where these partitions are used, or we can create a separate file and include it in the DTS file for each image; we will use the later method.

An example file devacademy_nrf9161_partition_conf.dtsi is shown below:

/*
 * Copyright (c) 2023 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */
&slot0_partition {
	reg = <0x00010000 0x40000>;
};

&slot0_ns_partition {
	reg = <0x00050000 0x30000>;
};

&slot1_partition {
	reg = <0x00080000 0x40000>;
};

&slot1_ns_partition {
	reg = <0x000c0000 0x30000>;
};

/* Default SRAM planning when building for nRF9161 with
 * ARM TrustZone-M support
 * - Lowest 88 kB SRAM allocated to Secure image (sram0_s).
 * - 40 kB SRAM reserved for and used by the modem library
 *   (sram0_modem). This memory is Non-Secure.
 * - Upper 128 kB allocated to Non-Secure image (sram0_ns).
 *   When building with TF-M, both sram0_modem and sram0_ns
 *   are allocated to the Non-Secure image.
 */

&sram0_s {
	reg = <0x20000000 DT_SIZE_K(88)>;
};

&sram0_modem {
	reg = <0x20016000 DT_SIZE_K(40)>;
};

&sram0_ns {
	reg = <0x20020000 DT_SIZE_K(128)>;
};
Devicetree

4.2 Create a common Devicetree file devacademy_nrf9161_common.dtsi (see Exercise 2 source code). In the common Devicetree file, you should include the partition file for Flash & RAM planning. You should also create one common pinctrl file devacademy_nrf9161_common-pinctrl.dtsi (see Exercise 2 source code).

Important

For use-cases where Multi-image build is utilized, the partitioning information provided in the Devicetree is ignored (aka the DTS partitioning). Instead, the Partition Mananger controls the partitions. This will be covered in-depth in Lesson 8 – Bootloaders and DFU/FOTA.

4.3 Create a per-image Devicetree file (devacademy_nrf9161.dts and devacademy_nrf9161_ns.dts) to select the chosen nodes for flash and RAM and disable peripherals allocated to the other image.

Example devacademy_nrf9161.dts :

/*
 * Copyright (c) 2023 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/dts-v1/;
#include <nordic/nrf9161_laca.dtsi>
#include "devacademy_nrf9161_common.dtsi"

/ {
	chosen {
		zephyr,sram = &sram0_s;
		zephyr,flash = &flash0;
		zephyr,code-partition = &slot0_partition;
		zephyr,sram-secure-partition = &sram0_s;
		zephyr,sram-non-secure-partition = &sram0_ns;
	};
};
Devicetree

Example devacademy_nrf9161_ns.dts :

/*
 * Copyright (c) 2023 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/dts-v1/;
#include <nordic/nrf9161ns_laca.dtsi>
#include "devacademy_nrf9161_common.dtsi"

/ {
	chosen {
		zephyr,flash = &flash0;
		zephyr,sram = &sram0_ns;
		zephyr,code-partition = &slot0_ns_partition;
	};
};

/* Disable UART1, because it is used by default in TF-M */
&uart1 {
	status = "disabled";
};
Devicetree

Register an account
Already have an account? Log in
(All fields are required unless specified optional)

  • 8 or more characters
  • Upper and lower case letters
  • At least one number or special character

Forgot your password?
Enter the email associated with your account, and we will send you a link to reset your password.