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
  • Hi Eliot,

    The bootloader setting is empty (all 0xFF) when the bootloader first flashed. It's a page in flash located at address BOOTLOADER_SETTINGS_ADDRESS (0x3FC00). On the first run the bootloader will check if there is any bootloader setting CRC written, if there is nothing, it will write the initial setting (which has only bootloader version and the CRC). Please have a look at nrf_dfu_settings_init() in nrf_dfu_setting.c

    If you have no button, you can remove the part that we check if the button is pressed. You will then need to enter bootloader by either erase the application valid flag (and its CRC) in the bootloader setting page (what happens when you have no app in the flash) or you can set enter_buttonless_dfu = 1 flag in the bootloader setting. Make sure bootloader setting CRC is updated also.

  • But I pasted my log above, and nowhere in there is nrf_dfu_settings_init() logging "!!!!!!!!!!!!!!! Resetting bootloader settings !!!!!!!!!!!". So the CRC must be either be 0xFFFFFFFF, or be valid. I expect it's 0xFFFFFFFF. But in that situation, the function just returns. It does NOT write a valid bootloader settings.

  • Most likely you haven't caught the first time the bootloader started (right after programming), and it already initialized.

    You can simply use nrfjprog to read the bootloader setting from flash of the chip and check what is inside. It's located at 0x3FC00.

  • Thanks, you're right and I had not caught the first run after flashing. When I do, nrf_dfu_settings_init() does its thing:

    :INFO:------- nrf_dfu_flash_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...
    
  • Here's my bootloader settings at this point:

    /Users/Eliot/dev/nRF5x_tools/nrfjprog/nrfjprog -f NRF51 -c 1000 --memrd 0x3FC00 --n 0x60
    0x0003FC00: AC871054 00000001 00000000 00000000   |T...............|
    0x0003FC10: 00000000 00000000 00000000 00000000   |................|
    0x0003FC20: 00000000 00000000 00000000 00000000   |................|
    0x0003FC30: 00000000 00000000 00000000 00000000   |................|
    0x0003FC40: 00000000 00000000 00000000 00000000   |................|
    0x0003FC50: 00000000 00000000 00000000 00000000   |................|
    
Related