Including a bootloader with an application

I want to include a dfu bootloader with an application.  I read here: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/nrf/app_dev/bootloaders_and_dfu/bootloader_adding.htmlthat I should include "CONFIG_SECURE_BOOT=y" in the prj.conf file. However when I do I get this most enigmatic error message: "FATAL ERROR: command exited with status 1: 'c:\ncs\toolchains\v2.3.0\opt\bin\cmake.EXE' --build 'c:\Nordic\MyApps\blinky\build'" at build time.

If I remove the "CONFIG_SECURE_BOOT=y" from the prj.conf file, the application builds normally,

Regards,

Jerry

Parents
  • Hi,

    I have tested myself when nRF Secure Immutable Bootloader (NSIB) as immutable bootloader is set to be used, with following configuration option

    CONFIG_SECURE_BOOT=y


    and when adding mcuboot as upgradable bootloader is chosen with configuration options given below.
    CONFIG_SECURE_BOOT=y
    CONFIG_BOOTLOADER_MCUBOOT=y


    I could not reproduce your issue and did not see build error.

    You could try building your application from both VS Code and command line using "west build". In addition, you could try using NCS v2.4.0 instead of v2.3.0. Lastly, check if your build environment is working correctly.

    Best regards,
    Dejan

  • Hi Dejan,

    I am using sdk version

    Below is a screen snippet which shows an error:

    This is supposed to be fixed by a pristine build; it isn't.

    I have pasted in several of my project files; I apologize, but I can't figure out hoe to attach files to this interface.

    Here is my prj.conf file:

    CONFIG_USB_DEVICE_STACK=y
    CONFIG_USB_DEVICE_PRODUCT="Zephyr USB console sample"
    CONFIG_USB_DEVICE_PID=0x0004
    #CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n

    #CONFIG_SERIAL=y
    CONFIG_CONSOLE=y
    CONFIG_UART_CONSOLE=y
    CONFIG_UART_LINE_CTRL=y
    CONFIG_SECURE_BOOT=y
    CONFIG_BOOTLOADER_MCUBOOT=y

    Here is my terminal log for a pristine build:

    CMake Warning at C:/ncs/v2.4.0/zephyr/subsys/usb/device/CMakeLists.txt:22 (message):
    CONFIG_USB_DEVICE_VID has default value 0x2FE3.

    This value is only for testing and MUST be configured for USB products.


    CMake Warning at C:/ncs/v2.4.0/zephyr/subsys/usb/device/CMakeLists.txt:28 (message):
    CONFIG_USB_DEVICE_PID has default value 0x100.

    This value is only for testing and MUST be configured for USB products.


    CMake Warning at C:/ncs/v2.4.0/nrf/lib/flash_patch/CMakeLists.txt:8 (message):

    ----------------------------------------------------------
    --- WARNING: To maintain the integrity of secure boot, ---
    --- enable CONFIG_DISABLE_FLASH_PATCH in production. ---
    ----------------------------------------------------------


    CMake Warning at C:/ncs/v2.4.0/zephyr/CMakeLists.txt:838 (message):
    No SOURCES given to Zephyr library: lib__libc__common

    Excluding target from build.


    MCUBoot bootloader key file: C:/ncs/v2.4.0/bootloader/mcuboot/root-ec-p256.pem
    -- Configuring done
    -- Generating done
    -- Build files have been written to: C:/Nordic/MyApps/console_example/build_dongle_db/mcuboot
    === child image mcuboot - end ===

    CMake Warning at C:/ncs/v2.4.0/nrf/modules/mcuboot/CMakeLists.txt:310 (message):

    ---------------------------------------------------------
    --- WARNING: Using default MCUBoot key, it should not ---
    --- be used for production. ---
    ---------------------------------------------------------

    CMake Warning at C:/ncs/v2.4.0/zephyr/CMakeLists.txt:838 (message):
    No SOURCES given to Zephyr library: lib__libc__common

    Excluding target from build.


    Traceback (most recent call last):
    File "C:/ncs/v2.4.0/nrf/scripts/partition_manager.py", line 1993, in <module>
    main()
    File "C:/ncs/v2.4.0/nrf/scripts/partition_manager.py", line 1028, in main
    solution.update(solve_region(pm_config, region, region_config,
    File "C:/ncs/v2.4.0/nrf/scripts/partition_manager.py", line 971, in solve_region
    get_region_config(partitions, region_config, static_partitions, system_reqs=pm_config)
    File "C:/ncs/v2.4.0/nrf/scripts/partition_manager.py", line 758, in get_region_config
    solve_complex_region(pm_config, start, size, placement_strategy, region_name, device, static_conf,
    File "C:/ncs/v2.4.0/nrf/scripts/partition_manager.py", line 865, in solve_complex_region
    solution, sub_partitions = resolve(pm_config, dp, system_reqs)
    File "C:/ncs/v2.4.0/nrf/scripts/partition_manager.py", line 308, in resolve
    solve_direction(reqs, sub_partitions, unsolved, solution, 'after')
    File "C:/ncs/v2.4.0/nrf/scripts/partition_manager.py", line 198, in solve_direction
    anchor = current if current in solution else next(solved for solved in reversed(solution)
    StopIteration
    CMake Error at C:/ncs/v2.4.0/nrf/cmake/partition_manager.cmake:304 (message):
    Partition Manager failed, aborting. Command:
    C:/ncs/toolchains/v2.3.0/opt/bin/python.exe;C:/ncs/v2.4.0/nrf/scripts/partition_manager.py;--input-f
    Call Stack (most recent call first):
    C:/ncs/v2.4.0/zephyr/cmake/modules/kernel.cmake:247 (include)
    C:/ncs/v2.4.0/zephyr/cmake/modules/zephyr_default.cmake:124 (include)
    C:/ncs/v2.4.0/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:66 (include)
    C:/ncs/v2.4.0/zephyr/share/zephyr-package/cmake/ZephyrConfig.cmake:92 (include_boilerplate)
    CMakeLists.txt:4 (find_package)


    -- Configuring incomplete, errors occurred!
    See also "C:/Nordic/MyApps/console_example/build_dongle_db/CMakeFiles/CMakeOutput.log".
    See also "C:/Nordic/MyApps/console_example/build_dongle_db/CMakeFiles/CMakeError.log".
    FATAL ERROR: command exited with status 1: 'c:\ncs\toolchains\v2.3.0\opt\bin\cmake.EXE' '-DWEST_PYTHON

    * The terminal process terminated with exit code: 1.
    * Terminal will be reused by tasks, press any key to close it.

    This is my nrf52480dongle_nrf52480.dts file:\

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

    /dts-v1/;
    #include <nordic/nrf52840_qiaa.dtsi>
    #include "nrf52840dongle_nrf52840-pinctrl.dtsi"

    / {
    model = "Nordic nRF52840 Dongle NRF52840";
    compatible = "nordic,nrf52840-dongle-nrf52840";

    chosen {
    zephyr,console = &cdc_acm_uart;
    zephyr,shell-uart = &cdc_acm_uart;
    zephyr,uart-mcumgr = &cdc_acm_uart;
    zephyr,bt-mon-uart = &cdc_acm_uart;
    zephyr,bt-c2h-uart = &cdc_acm_uart;
    zephyr,sram = &sram0;
    zephyr,flash = &flash0;
    zephyr,code-partition = &slot0_partition;
    zephyr,ieee802154 = &ieee802154;
    };

    leds {
    compatible = "gpio-leds";
    led0_green: led_0 {
    gpios = <&gpio0 6 GPIO_ACTIVE_LOW>;
    label = "Green LED 0";
    };
    led1_red: led_1 {
    gpios = <&gpio0 8 GPIO_ACTIVE_LOW>;
    label = "Red LED 1";
    };
    led1_green: led_2 {
    gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
    label = "Green LED 1";
    };
    led1_blue: led_3 {
    gpios = <&gpio0 12 GPIO_ACTIVE_LOW>;
    label = "Blue LED 1";
    };
    };

    pwmleds {
    compatible = "pwm-leds";
    red_pwm_led: pwm_led_0 {
    pwms = <&pwm0 0 PWM_MSEC(20) PWM_POLARITY_INVERTED>;
    };
    green_pwm_led: pwm_led_1 {
    pwms = <&pwm0 1 PWM_MSEC(20) PWM_POLARITY_INVERTED>;
    };
    blue_pwm_led: pwm_led_2 {
    pwms = <&pwm0 2 PWM_MSEC(20) PWM_POLARITY_INVERTED>;
    };
    };

    buttons {
    compatible = "gpio-keys";
    button0: button_0 {
    gpios = <&gpio1 6 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
    label = "Push button switch 0";
    };
    };

    /* These aliases are provided for compatibility with samples */
    aliases {
    sw0 = &button0;
    led0 = &led0_green;
    led1 = &led1_red;
    led2 = &led1_green;
    led3 = &led1_blue;
    led0-green = &led0_green;
    led1-red = &led1_red;
    led1-green = &led1_green;
    led1-blue = &led1_blue;
    pwm-led0 = &red_pwm_led;
    pwm-led1 = &green_pwm_led;
    pwm-led2 = &blue_pwm_led;
    red-pwm-led = &red_pwm_led;
    green-pwm-led = &green_pwm_led;
    blue-pwm-led = &blue_pwm_led;
    mcuboot-button0 = &button0;
    mcuboot-led0 = &led0_green;
    watchdog0 = &wdt0;
    };
    };

    &adc {
    status = "okay";
    };

    &gpiote {
    status = "okay";
    };

    &gpio0 {
    status = "okay";
    };

    &gpio1 {
    status = "okay";
    };

    &uart0 {
    compatible = "nordic,nrf-uarte";
    status = "okay";
    current-speed = <115200>;
    pinctrl-0 = <&uart0_default>;
    pinctrl-1 = <&uart0_sleep>;
    pinctrl-names = "default", "sleep";
    };

    &i2c0 {
    compatible = "nordic,nrf-twi";
    status = "okay";
    pinctrl-0 = <&i2c0_default>;
    pinctrl-1 = <&i2c0_sleep>;
    pinctrl-names = "default", "sleep";
    };

    &i2c1 {
    compatible = "nordic,nrf-twi";
    /* Cannot be used together with spi1. */
    /* status = "okay"; */
    pinctrl-0 = <&i2c1_default>;
    pinctrl-1 = <&i2c1_sleep>;
    pinctrl-names = "default", "sleep";
    };

    &pwm0 {
    status = "okay";
    pinctrl-0 = <&pwm0_default>;
    pinctrl-1 = <&pwm0_sleep>;
    pinctrl-names = "default", "sleep";
    };

    /*
    * By default, not adding all available SPI instances (spi2, spi3) due to
    * limited GPIOs available on dongle board.
    */
    &spi0 {
    compatible = "nordic,nrf-spi";
    /* Cannot be used together with i2c0. */
    /* status = "okay"; */
    pinctrl-0 = <&spi0_default>;
    pinctrl-1 = <&spi0_sleep>;
    pinctrl-names = "default", "sleep";
    };

    &spi1 {
    compatible = "nordic,nrf-spi";
    status = "okay";
    pinctrl-0 = <&spi1_default>;
    pinctrl-1 = <&spi1_sleep>;
    pinctrl-names = "default", "sleep";
    };

    &ieee802154 {
    status = "okay";
    };

    /* Include flash partition table.
    * Two partition tables are available:
    * fstab-stock -compatible with Nordic nRF5 bootloader, default
    * fstab-debugger -to use an external debugger, w/o the nRF5 bootloader
    */
    #include "fstab-stock.dts"

    zephyr_udc0: &usbd {
    compatible = "nordic,nrf-usbd";
    status = "okay";

    cdc_acm_uart: cdc_acm_uart {
    compatible = "zephyr,cdc-acm-uart";
    };
    };

    Here is my cmakelsts.txt file:

    # SPDX-License-Identifier: Apache-2.0

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

    FILE(GLOB app_sources src/*.c)
    target_sources(app PRIVATE ${app_sources})

    This is my overlay file:

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

    / {
    chosen {
    zephyr,console = &cdc_acm_uart0;
    };
    };

    &zephyr_udc0 {
    cdc_acm_uart0: cdc_acm_uart0 {
    compatible = "zephyr,cdc-acm-uart";
    };
    };

    This is my main.c file:

    /*
    * Copyright (c) 2016 Intel Corporation.
    *
    * SPDX-License-Identifier: Apache-2.0
    */

    #include <zephyr/kernel.h>
    #include <zephyr/sys/printk.h>
    #include <zephyr/usb/usb_device.h>
    #include <zephyr/usb/usbd.h>
    #include <zephyr/drivers/uart.h>
    #include <stdio.h>

    BUILD_ASSERT(DT_NODE_HAS_COMPAT(DT_CHOSEN(zephyr_console), zephyr_cdc_acm_uart),
    "Console device is not ACM CDC UART device");

    #if IS_ENABLED(CONFIG_USB_DEVICE_STACK_NEXT)
    USBD_CONFIGURATION_DEFINE(config_1,
    USB_SCD_SELF_POWERED,
    200);

    USBD_DESC_LANG_DEFINE(sample_lang);
    USBD_DESC_STRING_DEFINE(sample_mfr, "ZEPHYR", 1);
    USBD_DESC_STRING_DEFINE(sample_product, "Zephyr USBD ACM console", 2);
    USBD_DESC_STRING_DEFINE(sample_sn, "0123456789ABCDEF", 3);

    USBD_DEVICE_DEFINE(sample_usbd,
    DEVICE_DT_GET(DT_NODELABEL(zephyr_udc0)),
    0x2fe3, 0x0001);

    static int enable_usb_device_next(void)
    {
    int err;

    err = usbd_add_descriptor(&sample_usbd, &sample_lang);
    if (err) {
    return err;
    }

    err = usbd_add_descriptor(&sample_usbd, &sample_mfr);
    if (err) {
    return err;
    }

    err = usbd_add_descriptor(&sample_usbd, &sample_product);
    if (err) {
    return err;
    }

    err = usbd_add_descriptor(&sample_usbd, &sample_sn);
    if (err) {
    return err;
    }

    err = usbd_add_configuration(&sample_usbd, &config_1);
    if (err) {
    return err;
    }

    err = usbd_register_class(&sample_usbd, "cdc_acm_0", 1);
    if (err) {
    return err;
    }

    err = usbd_init(&sample_usbd);
    if (err) {
    return err;
    }

    err = usbd_enable(&sample_usbd);
    if (err) {
    return err;
    }

    return 0;
    }
    #endif /* IS_ENABLED(CONFIG_USB_DEVICE_STACK_NEXT) */

    void main(void)
    {
    const struct device *const dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));
    uint32_t dtr = 0;

    #if IS_ENABLED(CONFIG_USB_DEVICE_STACK_NEXT)
    #warning "CONFIG_USB_DEVICE_STACK_NEXT is enabled."
    if (enable_usb_device_next()) {
    return;
    }
    #else
    #warning "CONFIG_USB_DEVICE_STACK_NEXT is disabled."
    if (usb_enable(NULL)) {
    return;
    }
    #endif

    /* Poll if the DTR flag was set */
    while (!dtr) {
    uart_line_ctrl_get(dev, UART_LINE_CTRL_DTR, &dtr);
    /* Give CPU resources to low priority threads. */
    printf("waiting for DTR\n");
    k_sleep(K_MSEC(100));
    }

    while (1) {
    printf("Hello World! %s %s\n", CONFIG_ARCH, CONFIG_BOARD);
    k_sleep(K_SECONDS(1));
    }
    }

    Regards,

    Jerry

  • Hi Jerry,

    You could start by reading introduction part of NCS documentation, getting started guide and beyond getting started. We have extensive documentation which describes build and configuration system and updating repositories and tools. Specifically related to the dongle, there are guides about programming nrf52840 dongle and progamming and debugging nrf52840 dongle. We have many samples which can help you in your development and for each sample you can see the requirements.
    nrf52840 dongle does not have debug support and it is mostly used for testing. I would recommend nrf52840-dk as a development platform which you could also later use for flashing the dongle when needed.

    Best regards,
    Dejan

  • Dejan, 

    I think you and I have a communication problem.  Your comments above are correct and your points are all well known to me.  I never intended to use the dongle as a code debugging platform.  Rather, my notion was to deploy, say 10 or more, to test my software, its interconnectivity , responses and the like.  Now as to your recommendation that I use s nRF52840-DK for debugging my code, I couldn't agree with you more and is the reason I use the dk for debugging and have been doing so all along.

    So to clarify things for you, debugging has nothing to do with a bootloader; I'm at a loss as to how you got that idea.

    All I want to do is include a bootloader with my application that runs on the donglle.

    Previously, you responded as follows:

    "

    I have tested myself when nRF Secure Immutable Bootloader (NSIB) as immutable bootloader is set to be used, with following configuration option

    Fullscreen
    1
    CONFIG_SECURE_BOOT=y



    and when adding mcuboot as upgradable bootloader is chosen with configuration options given below.

    Fullscreen
    1
    2
    CONFIG_SECURE_BOOT=y
    CONFIG_BOOTLOADER_MCUBOOT=y



    I could not reproduce your issue and did not see build error.

    You could try building your application from both VS Code and command line using "west build". In addition, you could try using NCS v2.4.0 instead of v2.3.0. Lastly, check if your build environment is working correctly.

    Best regards,"

    This proves beyond all cavil, that this configuration is the correct one, at least for the nRF52840-dk.  It is my understanding that you subsequently attempted the build  for a dongle and that the build failed, similar to my experience.

    So to recap where we are: 

    1) When i include a bootloader for the dongle, the build fails.

    2) When I include a bootloader for the dk the build works.

    3) From the above, I believe  that you too can include a bootloader for the dk and that build works.

    4) From the above I believe that when you include a bootloader, you too, experience a build fail.

    If this is not a fair description of our status quo, please clarify it for me..  On the other hand, If this is a fair description of our status quo, what am I to expect from you concerning this problem?  Is there anything I can provide that might make your task easier?  I can zip up my project files for you if you think it might help?

    Regards,

    Jerry

  • Hi Jerry,

    Configuration option CONFIG_SECURE_BOOT is used for nRF Secure Immutable Bootloader (NSIB). Building with this option for nrf52840 dongle was not successful for me. Since you want to build the hello_world application with bootloader, you could alternatively build it with MCUboot as immutable bootloader by adding this configuration line
    in prj.conf:

    CONFIG_BOOTLOADER_MCUBOOT=y


    and in child_image\mcuboot.conf:
    CONFIG_PM_PARTITION_SIZE_MCUBOOT=0x7B800


    Best regards,
    Dejan

  • Ok, we seem to be going around in circles here.  We are just wasting each others time, so I'm done with this. There is no need to reply further.

    Regards,

    Jerry

  • Hi Jerry,

    I am sorry for a delayed reply. It is vacation time and we have reduced staffing. Delays in replying should be expected. Thank you for your patience and understanding.

    I have done further testing. Since adding CONFIG_SECURE_BOOT was not working for me, I have had an internal discussion with our developers.

    When using CONFIG_SECURE_BOOT=y in prj.conf, you might get some errors with cdc_acm. For this, the suggestion is to disable USB CDC for b0. However, USB CDC is enabled on the dongle by default. Therefore, you would need to disable USB CDC with CONFIG_BOARD_SERIAL_BACKEND_CDC_ACM=n. The way how this is supposed to be done can be found in our nRF_Desktop application. Please have a look at the configuration files located in
    v2.4.0\nrf\applications\nrf_desktop\configuration\nrf52840dongle_nrf52840 and
    v2.4.0\nrf\applications\nrf_desktop\configuration\nrf52840dongle_nrf52840\child_image\b0
    You could try changing your prj.conf and b0.conf (or prj.conf in child_image\b0) files by looking at above-mentioned files from nRF Desktop application. Alternatively, b0 configuration file could also be specified with configuration option  -Db0_CONF_FILE=b0.conf.

    Best regards,
    Dejan

Reply
  • Hi Jerry,

    I am sorry for a delayed reply. It is vacation time and we have reduced staffing. Delays in replying should be expected. Thank you for your patience and understanding.

    I have done further testing. Since adding CONFIG_SECURE_BOOT was not working for me, I have had an internal discussion with our developers.

    When using CONFIG_SECURE_BOOT=y in prj.conf, you might get some errors with cdc_acm. For this, the suggestion is to disable USB CDC for b0. However, USB CDC is enabled on the dongle by default. Therefore, you would need to disable USB CDC with CONFIG_BOARD_SERIAL_BACKEND_CDC_ACM=n. The way how this is supposed to be done can be found in our nRF_Desktop application. Please have a look at the configuration files located in
    v2.4.0\nrf\applications\nrf_desktop\configuration\nrf52840dongle_nrf52840 and
    v2.4.0\nrf\applications\nrf_desktop\configuration\nrf52840dongle_nrf52840\child_image\b0
    You could try changing your prj.conf and b0.conf (or prj.conf in child_image\b0) files by looking at above-mentioned files from nRF Desktop application. Alternatively, b0 configuration file could also be specified with configuration option  -Db0_CONF_FILE=b0.conf.

    Best regards,
    Dejan

Children
  • Unfortunately I am facing the same issue. I tried to include the b0.conf but no luck with that either. Once I enable CONFIG_SECURE_BOOT I am seeing this error. I modified the partition manager to dump the pool-variable right before it throws that StopIteration error, and at that point it looks like this:

    ['start', 'mcuboot', 'mcuboot_pad', 'app', 'nvs_storage', 'end', 'b0_container', 'app_image', 's0_image', 's0', 's1', 'mcuboot_primary_app', 'mcuboot_primary']

    To me it looks like it is trying to resolve some circular dependency there somehow, but I am not familiar with how it's supposed to work so I don't know if that's really the case. Maybe the developer/maintainer of that script can have a look and tell me what other variables I should dump to have a look at why it ends up in this state?

  • Hi  ,

    Could you provide more information about your application?

    Which NCS version do you use?

    Best regards,
    Dejan

  • What I need is the ability to update the firmware/application from the running application. That appears to require using mcuboot. When I only enable mcuboot it compiles. Additionally I want secureboot so I figured the best way would be to make mcuboot upgradable aswell so I enabled the first stage bootloader aswell.

    Another requirement is a config partition/nvs partition to store some data.

    I am using NCS 2.5.0. I think on the previous version I was at least able to compile it, but I've experienced other issues there.

  • Hi  ,

    For updating from application, you could look at SMP server sample, and unofficial central_smp_client_dfu or  smp_client_ble. You could also have a look at unofficial sample updatable bootloader. In addition, there is DevZone guide on how to add DFU support to your application.

    Best regards,
    Dejan

  • Well what are those examples worth if there's no way to use them as the partition manager is going crazy and there's no way to compile it? This issue needs to be fixed first, if my attempts at writing the images aren't successful afterwards I'll open another case, as that's completely unrelated to this issue.

    I tried to create a pm_static.yml file to define a layout that should be used, but I can't figure out how to tell it to create s0 and s1, aswell as mcuboot_primary_app and mcuboot_secondary_app and fill those with mcuboot and the app. Maybe you can provide a pm_static.yml file for using b0/mcuboot with secureboot? That should allow the compilation to run through as the broken partition_manager no longer needs to sort it out.

Related