This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Generating Production Image without DFU OTA

Due to time pressure, I'm starting this thread based on an existing ticket: https://devzone.nordicsemi.com/f/nordic-q-a/51423/firmware-on-custom-board-application-bootloader, so that I can get as many eyes on this as possible.

My setup:

  • Board: Custom PCB based on NRF52840
  • SDK: 15.2.0
  • Development Environment: Segger Embedded Studio

I am trying to assemble an image that can be flashed on the custom board at the factory. I have followed the Nordic tutorials, and I've gotten to the point where I can assemble an image (Application, Bootloader (+bootloader settings) and Softdevice). The problem is the device does not boot up.

Here's the situation:

  1. The custom board does not yet have a BLE antenna, so we cant do BLE DFU, yet
  2. All UARTS have been used up, so we can't do DFU via UART either
  3. The only viable path for now is to program the image using nrfjprog.

Questions:

  1. Any insights on why the device does not boot up?
  2. Regarding the private/public key aspects of the process, I understand the public key is linked with the bootloader project. How does one link the private key with the bootloader settings, if possible?
  3. Is there a way to bypass the key validation, because, again, right now we can't do DFU.
  4. There is a chance the issue might be the same as this: https://devzone.nordicsemi.com/f/nordic-q-a/19068/uploading-application-and-bootloader-application-not-starting.How do I do this in SDK 15.2.0?

Any and all insights are appreciated!

Thanks a mil,

Tim

  • Thanks for your elaborate troubleshooting! Very much appreciated!

    Well, I have been using a custom board based on the NRF52840.

    I decided yesterday to take a step back and try a much simpler application (the blinky freertos example), and the NRF52840 DK. I repeated the exact steps I've been doing so far (I expected all 4 LEDS to be blinking in a certain pattern as soon as the programming was finished). Instead LED1 and LED2 just lights up.

    Funny enough I then tried using my own application image, but this time on the DK. It was the same result - LED1 and LED2 just lights up. This is definitely some kind of error, as my custom board LED is mapped to P0.20, and the LEDs on the DK are mapped to P0.13 - P0.16.

    Can you try building an image using the blinky freertos example? If you can get that to work, then perhaps you could share exactly how you did it. That could hopefully be a good start to figuring this out.

    To answer your questions:

    1. Yes, I use SES,
    2. Regarding optimization, I open the project options, choose the Configuration (Debug/Release), then go to Code Generation. Finally I set the optimization level to None. Can you confirm this is the proper way to do it?

    In the meantime, I'll try using the debug version of the bootloader.

  • Update: I tried looking into why exactly LEDS 1 and 2 light up when the flashing is completed. Turns out that, in main.c (secure_bootloader_pca10056_ble), a function gets called (dfu_observer), which notifies of DFU events.

    By default, it's setup like this:

    static void dfu_observer(nrf_dfu_evt_type_t evt_type)
    {
        switch (evt_type)
        {
            case NRF_DFU_EVT_DFU_FAILED:
            case NRF_DFU_EVT_DFU_ABORTED:
            case NRF_DFU_EVT_DFU_INITIALIZED:
                bsp_board_init(BSP_INIT_LEDS);
                bsp_board_led_on(BSP_BOARD_LED_0);
                bsp_board_led_on(BSP_BOARD_LED_1);
                bsp_board_led_off(BSP_BOARD_LED_2);
                break;
            case NRF_DFU_EVT_TRANSPORT_ACTIVATED:
                bsp_board_led_off(BSP_BOARD_LED_1);
                bsp_board_led_on(BSP_BOARD_LED_2);
                break;
            case NRF_DFU_EVT_DFU_STARTED:
                break;
            default:
                break;
        }
    }

    I moved bsp_board_init(BSP_INIT_LEDS); to main, and changed the rest of the function to:

    static void dfu_observer(nrf_dfu_evt_type_t evt_type)
    {
        bsp_board_leds_off();
        
        switch (evt_type)
        {
            case NRF_DFU_EVT_DFU_FAILED:
                bsp_board_led_on(BSP_BOARD_LED_0); // LED1
            break;
            case NRF_DFU_EVT_DFU_ABORTED:
                bsp_board_led_on(BSP_BOARD_LED_1); // LED2
            break;
            case NRF_DFU_EVT_DFU_INITIALIZED:
                bsp_board_led_on(BSP_BOARD_LED_2); // LED3
                break;
            case NRF_DFU_EVT_TRANSPORT_ACTIVATED:
                bsp_board_led_on(BSP_BOARD_LED_3); // LED4
                break;
            case NRF_DFU_EVT_DFU_STARTED:
                bsp_board_led_on(BSP_BOARD_LED_0); // LED1
                bsp_board_led_on(BSP_BOARD_LED_1); // LED2
            default:
                break;
        }
    }

    On flashing the assembled image, LED3 turns on - which leads me to think it is stuck in DFU mode. This log confirms it:

    <info> app: Inside main
    <debug> app: In nrf_bootloader_init
    <debug> nrf_dfu_settings: Calling nrf_dfu_settings_init()...
    <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.
    <debug> nrf_dfu_settings: Settings OK
    <debug> app: Enter nrf_bootloader_fw_activate
    <info> app: No firmware to activate.
    <debug> app: Enter nrf_dfu_app_is_valid
    <debug> app: No valid app to boot.
    <debug> app: DFU mode because app is not valid.
    <info> nrf_bootloader_wdt: WDT is not enabled
    <debug> app: in weak nrf_dfu_init_user
    <debug> app: timer_stop (0x200057D4)
    <debug> app: timer_activate (0x200057D4)
    <info> app: Entering DFU mode.
    <debug> app: Initializing transports (found: 1)
    <debug> nrf_dfu_ble: Initializing BLE DFU transport
    <debug> nrf_dfu_ble: Setting up vector table: 0x000F1000
    <debug> nrf_dfu_ble: Enabling SoftDevice.
    <debug> nrf_dfu_ble: Configuring BLE stack.
    <debug> nrf_dfu_ble: Enabling the BLE stack.
    <debug> nrf_dfu_ble: No advertising name found
    <debug> nrf_dfu_ble: Using default advertising name
    <debug> nrf_dfu_ble: Advertising...
    <debug> nrf_dfu_ble: BLE DFU transport initialized.
    <debug> nrf_dfu_flash: Initializing nrf_fstorage_sd backend.
    <debug> app: Enter main loop

    As for using the debug version of the bootloader - how exactly do you use it? Specifically how do you load both the application and bootloader and debug?

  • Hello Tim,

     

    Tim Adu said:
    I decided yesterday to take a step back and try a much simpler application (the blinky freertos example), and the NRF52840 DK. I repeated the exact steps I've been doing so far (I expected all 4 LEDS to be blinking in a certain pattern as soon as the programming was finished). Instead LED1 and LED2 just lights up.

     This means that the bootloader has rejected the application, and the device is in DFU mode. You should be able to see the device advertising as "DfuTarg". 

    So if you programmed all 4 objects, SD, BL, BL_settings, and APP, this means that there is something wrong with your BL settings (signed with the wrong keys), or you have not programmed one of the files properly. 

    Can you please try to unzip a new unmodified SDK, so that you are sure you don't have anything changed in your SDK, and try the ble_app_buttonless application together with the bootloader. I have explained everything I know about bootloaders in the post that you link to in the top of this post, and I don't want to write it all again. 

    In your unmodified SDK, please create your own keys, public and private. compile the bootloader and the ble_app_buttonless_dfu example, and the bootloader, and copy their hex files to a folder, together with a copy of your keys and the softdevice. Then run the following .bat script. I saw your previous scripts, but I don't know where you link to, and whether the pats are correct. Let's keep everything very simple, until we get it working:

    nrfjprog -e
    nrfjprog --program softdevice.hex
    nrfjprog --program bootloader.hex
    nrfjprog --program ble_app_buttonless_dfu.hex
    nrfutil settings generate --family NRF52840 --application application.hex --application-version 1 --bootloader-version 1 --bl-settings-version 1 --key-file private.key bl_settings.hex
    nrfjprog --program bl_settings.hex
    nrfjprog --reset

    Do this before you look into the _debug version of the bootloader. 

  • Thanks Edvin,

    I followed your reccommendations and was able to generate a production image that worked. Then I tried with an even simpler application (ble_app_blinky) and was able to get it to work as well.

    Then I tried using the debug bootloader with my application. It came in very handy as I could see that it actually accepted the app and the app did load, but something else was blocking from running further. It was my logger Cold sweat

    In my application I am using RTT as the logger backend since I have exhausted all my UARTS. The problem was the macro

    SEGGER_RTT_CONFIG_DEFAULT_MODE

    was by default set to 2 (blocking mode). I set it to 0 and it works perfectly!

    I'm not sure how much of a difference it makes, but I also used the --no-backup option when generating the bootloader settings.

    Thanks for all your help!

    Tim

Related