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

SDK 12.1.0 bootloader does not run application

I'm using the example bootloader from SDK 12.1.0 with gcc, nRF51822, S130. I flash the SD, bootloader and my application in that order like this:

flash: all
	$(NRFPROJ) --eraseall
	$(NRFPROJ) --program $(SOFTDEVICE)
	$(NRFPROJ) --program bootloader/biketracker_debug/armgcc/_build/bootloader_s130.hex
	$(NRFPROJ) --program $(HEX)
	$(NRFPROJ) --reset

When debugging the bootloader, I see this (with some extra logging I added in SDK sources)

:INFO:Inside main
:INFO:In nrf_bootloader_init
:INFO:In real nrf_dfu_init
:INFO:running nrf_dfu_settings_init
:INFO:Enter nrf_dfu_continue
:INFO:bank_current is NRF_DFU_CURRENT_BANK_0. Using bank_0.
:INFO:p_bank image_size: 0, image_crc: 0, bank_code: 0.
:INFO:Single: Invalid bank
:INFO:Application sent bootloader request
:INFO:In nrf_dfu_transports_init
:INFO:num transports: 1
:INFO:vector table: 0x00038000
SDH:INFO:sd_ble_enable: RAM START at 0x200025e0
:INFO:After nrf_dfu_transports_init
:INFO:------- nrf_dfu_flash_init-------
:INFO:Waiting for events

The first question is, should I be concerned that nrf_dfu_continue_bank() complains about "Single: Invalid bank". It looks like there's nothing in s_dfu_settings at all.

Secondly, this is a custom board and I have no buttons on it. nrf_dfu_enter_check() may be checking nrf_gpio_pin_read(BOOTLOADER_BUTTON) and reading a pin that I'm using for something completely unrelated. How do I override the implementation of nrf_dfu_enter_check()?

Edit 1

If I can get past that, I'll still need something valid here:

bool nrf_dfu_app_is_valid(void)
{
    NRF_LOG_INFO("Enter nrf_dfu_app_is_valid\r\n");
    if (s_dfu_settings.bank_0.bank_code != NRF_DFU_BANK_VALID_APP)
    {
       // Bank 0 has no valid app. Nothing to boot
       NRF_LOG_INFO("Return false in valid app check\r\n");
       return false;
    }
...

How is s_dfu_settings set? Here's a bit of my .Map file.

.bootloaderSettings
                0x000000000003fc00      0x400
 .bootloaderSettings
                0x000000000003fc00      0x400 /var/folders/dn/mqg_0vcj2zbfn7sp136z17gw0000gn/T//ccqgNNlW.ltrans4.ltrans.o
                0x000000000003fc00                m_dfu_settings_buffer

Edit 2

Having been enlightened to the need to generate a bootloader settings hex and flash it, I now find that even having done that, the bootloader sees 0x0 as the settings CRC and rewrites it.

Build output:

Generating bootloader settings hex.
~/Library/Python/2.7/bin/nrfutil settings generate --family NRF51 --application _build/biketracker_app_s130.hex --application-version 1 --bootloader-version 1 --bl-settings-version 1 _build/bootloader_settings.hex

Generated Bootloader DFU settings .hex file and stored it in: _build/bootloader_settings.hex

Bootloader DFU Settings:
* File:                 _build/bootloader_settings.hex
* Family:               nRF51
* CRC:                  0xD96D31B3
* Settings Version:     0x00000001 (1)
* App Version:          0x00000001 (1)
* Bootloader Version:   0x00000001 (1)
* Bank Layout:          0x00000000
* Current Bank:         0x00000000
* Application Size:     0x0001B6C8 (112328 bytes)
* Application CRC:      0x51B13C4A
* Bank0 Bank Code:      0x00000001

Erasing flash. Note that this will destroy any bonds on the device. Remember to also destroy them on the central (phone).
/Users/Eliot/dev/nRF5x_tools/nrfjprog/nrfjprog -f NRF51 -c 1000 --eraseall
Erasing code and UICR flash areas.
Applying system reset.
Programming soft device.
/Users/Eliot/dev/nRF5x_tools/nrfjprog/nrfjprog -f NRF51 -c 1000 --program /Users/Eliot/dev/nRF5_SDK_12.1.0_0d23e2a/components/softdevice/s130/hex/s130_nrf51_2.0.1_softdevice.hex
Parsing hex file.
Reading flash area to program to guarantee it is erased.
Checking that the area to write is not protected.
Programing device.
Programming bootloader.
/Users/Eliot/dev/nRF5x_tools/nrfjprog/nrfjprog -f NRF51 -c 1000 --program bootloader/biketracker_debug/armgcc/_build/bootloader_s130.hex
Parsing hex file.
Reading flash area to program to guarantee it is erased.
Checking that the area to write is not protected.
Programing device.
Programming application.
/Users/Eliot/dev/nRF5x_tools/nrfjprog/nrfjprog -f NRF51 -c 1000 --program _build/biketracker_app_s130.hex
Parsing hex file.
Reading flash area to program to guarantee it is erased.
Checking that the area to write is not protected.
Programing device.
Erasing page for bootloader settings.
/Users/Eliot/dev/nRF5x_tools/nrfjprog/nrfjprog -f NRF51 -c 1000 --erasepage 0x0003FC00
Erasing addresses 0x3FC00 to 0x3FFFF.
Programming bootloader settings.
/Users/Eliot/dev/nRF5x_tools/nrfjprog/nrfjprog -f NRF51 -c 1000 --program _build/bootloader_settings.hex
Parsing hex file.
Reading flash area to program to guarantee it is erased.
Checking that the area to write is not protected.
Programing device.
Reading back bootloader settings from 0x3FC00.
/Users/Eliot/dev/nRF5x_tools/nrfjprog/nrfjprog -f NRF51 -c 1000 --memrd 0x3FC00 --n 0x60
0x0003FC00: D96D31B3 00000001 00000001 00000001   |.1m.............|
0x0003FC10: 00000000 00000000 0001B6C8 51B13C4A   |............J<.Q|
0x0003FC20: 00000001 00000000 00000000 00000000   |................|
0x0003FC30: 00000000 00000000 00000000 00000000   |................|
0x0003FC40: 00000000 00000000 00000000 00000000   |................|
0x0003FC50: 00000000 00000000 00000000 FFFFFFFF   |................|

Log from the bootloader, with some extra logging added:

:INFO:Inside main
:INFO:In nrf_bootloader_init
:INFO:In real nrf_dfu_init
:INFO:running nrf_dfu_settings_init
:INFO:s_dfu_settings.crc: 0x0
:INFO:!!!!!!!!!!!!!!! Resetting bootloader settings !!!!!!!!!!!
:INFO:Erasing old settings at: 0x0003fc00
:INFO:Erasing: 0x0003fc00, num: 1
:INFO:Writing 0x00000057 words
:INFO:Writing settings...
:INFO:Enter nrf_dfu_continue
:INFO:bank_current is NRF_DFU_CURRENT_BANK_0. Using bank_0.
:INFO:p_bank image_size: 0, image_crc: 0, bank_code: 0.
:INFO:Single: Invalid bank
:INFO:nrf_dfu_enter_check(): Returning false.
:INFO:Enter nrf_dfu_app_is_valid
:INFO:Return false in valid app check
:INFO:In nrf_dfu_transports_init
:INFO:num transports: 1
:INFO:vector table: 0x00038000
SDH:INFO:sd_ble_enable: RAM START at 0x200025e0
:INFO:After nrf_dfu_transports_init
:INFO:------- nrf_dfu_flash_init-------
:INFO:Waiting for events
  • Sorry, spoke too soon. That output is when I flash the application without the bootloader. Give me some time to build a monolithic hex file that I can run with gdb and I'll see if I can get the bootloader to run the application.

  • OK, I'm now able to debug my bootloader and this is the log from the first run. It resets the bootloader settings just fine, but then decides my application is not valid and refuses to run it.

  • Log:

    :INFO:In real nrf_dfu_init
    :INFO:running nrf_dfu_settings_init
    :INFO:!!!!!!!!!!!!!!! Resetting bootloader settings !!!!!!!!!!!
    :INFO:Erasing old settings at: 0x0003fc00
    :INFO:Erasing: 0x0003fc00, num: 1
    :INFO:Writing 0x00000057 words
    :INFO:Writing settings...
    :INFO:Enter nrf_dfu_continue
    :INFO:bank_current is NRF_DFU_CURRENT_BANK_0. Using bank_0.
    :INFO:p_bank image_size: 0, image_crc: 0, bank_code: 0.
    :INFO:Single: Invalid bank
    :INFO:nrf_dfu_enter_check(): Returning false.
    :INFO:Enter nrf_dfu_app_is_valid
    :INFO:Return false in valid app check
    :INFO:In nrf_dfu_transports_init
    :INFO:num transports: 1
    :INFO:vector table: 0x00038000
    SDH:INFO:sd_ble_enable: RAM START at 0x200025e0
    :INFO:After nrf_dfu_transports_init
    :INFO:------- nrf_dfu_flash_init-------
    :INFO:Waiting for events
    
  • Hi Eliot,

    You need to tell the bootloader that you have a valid app that you flashed in the chip. The bootloader won't be able to detect it automatically. It was made that it only acknowledge a valid app when it actually update it via DFU process.

    What you can do is either do a DFU and then read out the bootloader setting in the flash, and re-use that data when you set-up another board (with same application). Actually you can read out the whole flash and the simply flash that image to another board. I'm talking about production programming here.

    A more elegant solution is to generate the bootloader setting by using nrfutil tool. Please have a look here. After that you can merge the setting .hex to the bootloader (and the rest e.g application, softdevice etc). Use mergehex.exe to merge.

  • Converted your comment to an answer. It's disappointing that none of this is addressed by the example apps. I'm not sure how anyone's supposed to figure this out.

    My build now generates a hex file for the bootloader settings. I can't merge it with the bootloader hex file though, because the bootloader also has a .bootloaderSettings memory SECTION.

Related