Problem configuring and building nRF9160 custom board with TFM

I am programming some board bring-up firmware based on the MOSH sample for our custom board that uses the nRF9160.

NCS 2.3.0, VS Code, Windows 11

So far I have successfully added an out-of-tree driver for my out-of-tree board and added an extra command in MOSH to control a peripheral using the driver.

Now I want to add the modem library so that I can start integrating the commands for the modem. This is where I get stuck.

I read that the application has to be built for a non-secure board version to use the modem library. So I'm trying to follow the info available here: 

I added the Kconfig parameters for TFM to my board's defconfig:


Then the build system complained that BUILD_WITH_TFM was missing a dependency, so I added CONFIG_ARM_TRUSTZONE_M=y too.

Now the build fails at the point where it is creating the object file for zephyr/CMakeFiles/zephyr.dir/soc/arm/nordic_nrf/validate_base_addresses.c.obj:

[70/268] Building C object zephyr/CMakeFiles/zephyr.dir/lib/os/reboot.c.obj
[71/268] Building C object zephyr/CMakeFiles/zephyr.dir/soc/arm/nordic_nrf/validate_base_addresses.c.obj
FAILED: zephyr/CMakeFiles/zephyr.dir/soc/arm/nordic_nrf/validate_base_addresses.c.obj 
D:\ncs\toolchains\v2.3.0\opt\zephyr-sdk\arm-zephyr-eabi\bin\arm-zephyr-eabi-gcc.exe -DKERNEL -DMBEDTLS_CONFIG_FILE=\"nrf-config.h\" -DMBEDTLS_USER_CONFIG_FILE=\"nrf-config-user.h\" -DNRF9160_XXAA -DNRF_SKIP_FICR_NS_COPY_TO_RAM -DNRF_TRUSTZONE_NONSECURE -DPROJECT_NAME=board-bring-up-oot -DUSE_PARTITION_MANAGER=1 -D_ANSI_SOURCE -D_FORTIFY_SOURCE=1 -D__LINUX_ERRNO_EXTENSIONS__ -D__PROGRAM_START -D__ZEPHYR__=1 -ID:/ncs/v2.3.0/zephyr/kernel/include -ID:/ncs/v2.3.0/zephyr/arch/arm/include -Itfm/install/interface/include -ID:/ncs/v2.3.0/zephyr/include -Izephyr/include/generated -ID:/ncs/v2.3.0/zephyr/soc/arm/nordic_nrf/nrf91 -ID:/ncs/v2.3.0/zephyr/lib/libc/newlib/include -ID:/ncs/v2.3.0/zephyr/soc/arm/nordic_nrf/common/. -ID:/ncs/v2.3.0/nrf/include -ID:/ncs/v2.3.0/nrf/ext/freebsd-getopt/. -ID:/ncs/v2.3.0/nrf/include/tfm -ID:/ncs/v2.3.0/nrf/tests/include -Itfm/generated/interface/include -ID:/ncs/v2.3.0/modules/lib/cjson -ID:/ncs/v2.3.0/nrf/modules/cjson/include -ID:/ncs/v2.3.0/modules/hal/cmsis/CMSIS/Core/Include -ID:/ncs/v2.3.0/modules/hal/nordic/nrfx -ID:/ncs/v2.3.0/modules/hal/nordic/nrfx/drivers/include -ID:/ncs/v2.3.0/modules/hal/nordic/nrfx/mdk -ID:/ncs/v2.3.0/zephyr/modules/hal_nordic/nrfx/. -ID:/ncs/v2.3.0/modules/debug/segger/SEGGER -ID:/ncs/v2.3.0/modules/debug/segger/Config -ID:/ncs/v2.3.0/zephyr/modules/segger/. -ID:/_projects/cm1-nordic/board-bring-up/cm1_module/drivers/gpio_ext/. -ID:/_projects/cm1-nordic/board-bring-up/cm1_module/. -ID:/ncs/v2.3.0/nrfxlib/nrf_modem/include -ID:/_projects/cm1-nordic/board-bring-up/src/mosh/print/. -Imodules/nrfxlib/nrfxlib/nrf_security/src/include/generated -ID:/ncs/v2.3.0/nrfxlib/nrf_security/include -ID:/ncs/v2.3.0/nrfxlib/nrf_security/include/mbedtls -ID:/ncs/v2.3.0/modules/crypto/mbedtls/include -ID:/ncs/v2.3.0/modules/crypto/mbedtls/include/mbedtls -ID:/ncs/v2.3.0/modules/crypto/mbedtls/include/psa -ID:/ncs/v2.3.0/modules/crypto/mbedtls/library -ID:/ncs/v2.3.0/nrfxlib/crypto/nrf_oberon/include/mbedtls -ID:/ncs/v2.3.0/nrfxlib/crypto/nrf_oberon/include -fno-strict-aliasing -Os -imacros D:/_projects/cm1-nordic/board-bring-up/build/zephyr/include/generated/autoconf.h -ffreestanding -fno-common -g -gdwarf-4 -fdiagnostics-color=always -mcpu=cortex-m33 -mthumb -mabi=aapcs -mfpu=fpv5-sp-d16 -mfloat-abi=hard -mfp16-format=ieee --sysroot=D:/ncs/toolchains/v2.3.0/opt/zephyr-sdk/arm-zephyr-eabi/arm-zephyr-eabi -imacros D:/ncs/v2.3.0/zephyr/include/zephyr/toolchain/zephyr_stdint.h -Wall -Wformat -Wformat-security -Wno-format-zero-length -Wno-main -Wno-pointer-sign -Wpointer-arith -Wexpansion-to-defined -Wno-unused-but-set-variable -Werror=implicit-int -fno-pic -fno-pie -fno-asynchronous-unwind-tables -fno-reorder-functions --param=min-pagesize=0 -fno-defer-pop -fmacro-prefix-map=D:/_projects/cm1-nordic/board-bring-up=CMAKE_SOURCE_DIR -fmacro-prefix-map=D:/ncs/v2.3.0/zephyr=ZEPHYR_BASE -fmacro-prefix-map=D:/ncs/v2.3.0=WEST_TOPDIR -ffunction-sections -fdata-sections -specs=nano.specs -std=c99 -MD -MT zephyr/CMakeFiles/zephyr.dir/soc/arm/nordic_nrf/validate_base_addresses.c.obj -MF zephyr\CMakeFiles\zephyr.dir\soc\arm\nordic_nrf\validate_base_addresses.c.obj.d -o zephyr/CMakeFiles/zephyr.dir/soc/arm/nordic_nrf/validate_base_addresses.c.obj -c D:/ncs/v2.3.0/zephyr/soc/arm/nordic_nrf/validate_base_addresses.c
In file included from D:\ncs\v2.3.0\zephyr\include\zephyr\toolchain.h:50,
                 from D:\ncs\v2.3.0\zephyr\include\zephyr\kernel_includes.h:19,
                 from D:\ncs\v2.3.0\zephyr\include\zephyr\kernel.h:17,
                 from D:\ncs\v2.3.0\zephyr\soc\arm\nordic_nrf\validate_base_addresses.c:7:
D:\ncs\v2.3.0\zephyr\include\zephyr\toolchain\gcc.h:78:36: error: static assertion failed: ""
   78 | #define BUILD_ASSERT(EXPR, MSG...) _Static_assert(EXPR, "" MSG)
      |                                    ^~~~~~~~~~~~~~

Could someone please tell me what I am doing wrong here?

I've zipped up my code and added it here:

Board definition: CM11C0BC010007001

  • Hi,

    Could you provide full error log (Insert -> Image/Video/File, choose File and press Upload)?

    Do you migrate your project from some previous NCS version to NCS v2.3.0? If so, please have a look at migration guide and pin control.

    Since you made your own board, you could start by inspecting the configuration which is specified in the board file well as dts and dtsi files, and verifying your devicetree configuration.

    Best regards,

  • Hi Dejan,

    I had to upload the build output text file as a zip file:

    I did not migrate my project from a previous version of NCS, I started with v2.3.0. That said, I might have created the board definition in a slightly earlier version of NCS using the Create a new board wizard in VS Code.

    I'll look at the links you posted in the meantime, just in case I missed something. I have inspected the nrf9160dk_ns defconfig file, but I suppose I'll look at it again for some hints.

    I'll report back with what I find out. Thanks.

  • I cannot solve this based on your suggestions.

    I looked at the migration guide - it doesn't apply in my case, I made this board definition with the NCS 2.x.x.

    I have looked at and tried to copy the nrf9160dk_nrf9160_ns_defconfig file to the best of my ability. It still does not work.

    I can't tell if it is somehow due to defining i2c1 as a node in the devicetree. I read everywhere that you have to disable uart1 in your application for TFM to use it. But if uart1 is disabled, I assume that means I cannot enable other peripherals on x1 either, like i2c1 or spi1. Then I read that if you need to use uart1 in your app, you can just configure TFM to be silent and then you don't need to disable uart1 for your app.

    Further help from Nordic would be appreciated.

  • I seem to have found the problem.

    If anyone else encounters similar problems with defining a custom, non-secure board for NCS 2.3.0, here is what I learned:


    # Copyright (c) 2022 Nordic Semiconductor ASA
    # SPDX-License-Identifier: Apache-2.0
    # Replace <board-name> with actual board name
    # Enable MPU
    # Enable hardware stack protection
    # Enable TrustZone-M
    # This Board implies building Non-Secure firmware, necessary for using modem library
    # Setting TFM log level to silence should allow you to use UART1 in your application

    For the defconfig file, make sure to define the following parameters with =y:


    The last one - CONFIG_TFM_LOG_LEVEL_SILENCE - is optional; add this if your application needs uart1 (or potentially any other x1 peripheral, like i2c1).

    I got this tip from the answer to another, slightly older DevZone post -  Create a custom board with the build-in Create a new board wizard. 


    // Copyright (c) 2022 Nordic Semiconductor ASA
    // SPDX-License-Identifier: Apache-2.0
    #include <nordic/nrf9160ns_sica.dtsi>
    #include "<board-name>-pinctrl.dtsi"
    / {
    	chosen {
    		zephyr,flash = &flash0;
    		zephyr,sram = &sram0_ns;
    		zephyr,code-partition = &slot0_ns_partition;
    / {
    	reserved-memory {
    		#address-cells = <1>;
    		#size-cells = <1>;
    		sram0_s: image_s@20000000 {
    			/* Secure image memory */
    			reg = <0x20000000 DT_SIZE_K(88)>;
    		sram0_modem: image_modem@20016000 {
    			/* Modem (shared) memory */
    			reg = <0x20016000 DT_SIZE_K(40)>;
    		sram0_ns: image_ns@20020000 {
    			/* Non-Secure image memory */
    			reg = <0x20020000 DT_SIZE_K(128)>;

    The source of my problem was in the main DTS file. On line 5, when including the DTSI for the nRF9160, make sure you have the ns in #include <nordic/nrf9160ns_sica.dtsi>.

    I did not realize there was a difference when I created my board definition, and instead included the secure DTSI.


    If you do silence the TFM logging, then you do not have to disable uart1 (or other x1 peripherals).

    I added the extra defintions for the reserved-memory node based on the DK board definitions. 

    After finding the problem with the include in the DTS file, I can now successfully build my application with the modem library and AT shell included and successfully flash and run it on my custom hardware.

    I only figured out the problem after I copied over the directory for the DK board and started stripping out things I didn't need piecemeal.