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

[SDK12][PCA10040]ble_app_buttonless_dfu not resetting to bootloader

Hi,

I have modified my files as mentioned here. When I upload the package, the template device show and I am able to connect. But when I subscribe to the notification and write 0x01, the device doesn't reboot.

In bootloader log it asks to change the ram start address:

:INFO:Inside main
:INFO:In nrf_bootloader_init
:INFO:In real nrf_dfu_init
:INFO:running nrf_dfu_settings_init
:INFO:!!!!!!!!!!!!!!! Resetting bootloader settings !!!!!!!!!!!
:INFO:Erasing old settings at: 0x0007f000
:INFO:Erasing: 0x0007f000, num: 1
:INFO:Writing 0x00000057 words
:INFO:Writing settings...
:INFO:Enter nrf_dfu_continue
:INFO:Single: Invalid bank
: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: 0x00075000
SDH:INFO:sd_ble_enable: RAM START at 0x20002c00
SDH:WARNING:sd_ble_enable: app_ram_base should be adjusted to 0x20002798
SDH:WARNING:ram size should be adjusted to 0xd868 
:INFO:After nrf_dfu_transports_init
:INFO:------- nrf_dfu_flash_init-------
:INFO:Waiting for events

Here is the log without changing the base address:

SDH:INFO:sd_ble_enable: RAM START at 0x20002128
:INFO:running nrf_dfu_settings_init
:INFO:!!!!!!!!!!!!!!! Resetting bootloader settings !!!!!!!!!!!
:INFO:Erasing old settings at: 0x200021ac
:INFO:Erasing: 0x200021ac, num: 1
:INFO:Erase failed: 6
:INFO:Failed to erase bootloader settings
APP:INFO:Indication for BLE_DFU is enabled
APP:INFO:Indication for BLE_DFU is disabled
APP:INFO:Indication for BLE_DFU is enabled
APP:INFO:Device is entering bootloader mode!
:INFO:Erasing old settings at: 0x200021ac
:INFO:Erasing: 0x200021ac, num: 1
:INFO:Erase failed: 6
:INFO:Failed to erase bootloader settings

Here is the log after changing the address:

SDH:INFO:sd_ble_enable: RAM START at 0x20002128
:INFO:running nrf_dfu_settings_init
:INFO:!!!!!!!!!!!!!!! Resetting bootloader settings !!!!!!!!!!!
:INFO:Erasing old settings at: 0x200021ac
:INFO:Erasing: 0x200021ac, num: 1
:INFO:Erase failed: 6
:INFO:Failed to erase bootloader settings
APP:INFO:Indication for BLE_DFU is enabled
APP:INFO:Device is entering bootloader mode!
:INFO:Erasing old settings at: 0x200021ac
:INFO:Erasing: 0x200021ac, num: 1
:INFO:Erase failed: 6
:INFO:Failed to erase bootloader settings

I have tried with both debug bootloader and normal one, the problem remains the same. I am using GCC on Linux. Please help.

Thanks in advance :)


[EDIT]

When I power on the board with BUTTON 4 pressed, the device starts in bootloader mode. Here is the log:

: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:Valid App
:INFO:Application sent bootloader request
:INFO:In nrf_dfu_transports_init
:INFO:num transports: 1
:INFO:vector table: 0x00075000
SDH:INFO:sd_ble_enable: RAM START at 0x20002c00
SDH:WARNING:sd_ble_enable: app_ram_base should be adjusted to 0x20002798
SDH:WARNING:ram size should be adjusted to 0xd868 
:INFO:After nrf_dfu_transports_init
:INFO:------- nrf_dfu_flash_init-------
:INFO:Waiting for events

Also LED3 and LED1 are turned on in this state, not LED4. If I connect LED2 will turn on and LED1 will turn off. I guess this is the desired result right?


[EDIT]

This is the process that I'm following:

  • Erase the flash

  • Program Softdevice from buttonless_dfu Makefile using make flash_softdevice

  • Program bootloader_secure from pca10040_debug Makefile using make flash

  • Create package in buttonless_dfu directory using

    nrfutil pkg generate --debug-mode --key-file priv.pem --application _build/nrf52832_xxaa.hex pkg.zip

  • Transfer the zip to phone and upload using nrfConnect

  • Successfully upload the file

  • Device resets.

  • Connect to the device and enable notification on the unknown characteristic

  • Write 0x01 on the characteristic

  • The received response is 20-01-01, and the logs are as mentioned in the question.

I hope I am not doing anything wrong here.

Parents
  • Update .zip: dfu.zip

    bootloader nrf52832_xxaa_s132.hex

    EDIT:

    I took a look how bootloader setting address is defined and this seems like relevant part:

    #if defined (__CC_ARM )
    
        uint8_t  m_dfu_settings_buffer[CODE_PAGE_SIZE] __attribute__((at(BOOTLOADER_SETTINGS_ADDRESS)))
                                                       __attribute__((used));
    
    #elif defined ( __GNUC__ )
    
        uint8_t m_dfu_settings_buffer[CODE_PAGE_SIZE] __attribute__ ((section(".bootloaderSettings")))
                                                      __attribute__((used));
    

    So for Keil you have a fixed address but for gcc there should be a custom section in linker file named ".bootloaderSettings". Question is have you implemented it? I think that it should be placed in both bootloader and application linker file.

    And this is very similar to fstorage bug form SDK11 where the difference between Keil and gcc was exactly the same as here - fixed flash address vs. custom section.

    EDIT2:

    Following linker file for buttonless_dfu app fixes the problem:

    /* Linker script to configure memory regions. */
    
    SEARCH_DIR(.)
    GROUP(-lgcc -lc -lnosys)
    
    MEMORY
    {
      FLASH (rx) : ORIGIN = 0x1f000, LENGTH = 0x61000
      RAM (rwx) :  ORIGIN = 0x20002128, LENGTH = 0xded8
      
      /** Location of bootloader setting in flash. */
      BOOTLOADER_SETTINGS (rw) : ORIGIN = 0x0007F000, LENGTH = 0x1000
    }
    
    SECTIONS
    {
       /* Place the bootloader settings page in flash. */
      .bootloaderSettings(NOLOAD) :
      {
    
      } > BOOTLOADER_SETTINGS
      
      .fs_data :
      {
        PROVIDE(__start_fs_data = .);
        KEEP(*(.fs_data))
        PROVIDE(__stop_fs_data = .);
      } > RAM
    } INSERT AFTER .data;
    
    INCLUDE "nrf5x_common.ld"
    

    Original one was lacking .bootloaderSettings section

Reply
  • Update .zip: dfu.zip

    bootloader nrf52832_xxaa_s132.hex

    EDIT:

    I took a look how bootloader setting address is defined and this seems like relevant part:

    #if defined (__CC_ARM )
    
        uint8_t  m_dfu_settings_buffer[CODE_PAGE_SIZE] __attribute__((at(BOOTLOADER_SETTINGS_ADDRESS)))
                                                       __attribute__((used));
    
    #elif defined ( __GNUC__ )
    
        uint8_t m_dfu_settings_buffer[CODE_PAGE_SIZE] __attribute__ ((section(".bootloaderSettings")))
                                                      __attribute__((used));
    

    So for Keil you have a fixed address but for gcc there should be a custom section in linker file named ".bootloaderSettings". Question is have you implemented it? I think that it should be placed in both bootloader and application linker file.

    And this is very similar to fstorage bug form SDK11 where the difference between Keil and gcc was exactly the same as here - fixed flash address vs. custom section.

    EDIT2:

    Following linker file for buttonless_dfu app fixes the problem:

    /* Linker script to configure memory regions. */
    
    SEARCH_DIR(.)
    GROUP(-lgcc -lc -lnosys)
    
    MEMORY
    {
      FLASH (rx) : ORIGIN = 0x1f000, LENGTH = 0x61000
      RAM (rwx) :  ORIGIN = 0x20002128, LENGTH = 0xded8
      
      /** Location of bootloader setting in flash. */
      BOOTLOADER_SETTINGS (rw) : ORIGIN = 0x0007F000, LENGTH = 0x1000
    }
    
    SECTIONS
    {
       /* Place the bootloader settings page in flash. */
      .bootloaderSettings(NOLOAD) :
      {
    
      } > BOOTLOADER_SETTINGS
      
      .fs_data :
      {
        PROVIDE(__start_fs_data = .);
        KEEP(*(.fs_data))
        PROVIDE(__stop_fs_data = .);
      } > RAM
    } INSERT AFTER .data;
    
    INCLUDE "nrf5x_common.ld"
    

    Original one was lacking .bootloaderSettings section

Children
  • Your files work. Seems like a problem with GCC setup then. I'd like to mention that in the Makefile of bootloader, in target flash I have removed --chiperase, so that the softdevice is not removed. I doubt that is the cause but thought it might be worth mentioning. I'll wait for a response from nordic team. Thanks for help :)

  • I have not implemented ".bootloaderSettings", will look at it. If this was a bug in SDK11 too, I didn't have any problem in it. I have been using DFU with GCC since SDK9 and haven't experienced this issue. Might be luck, but I'll take a look.

  • and it seems we have a winner :)

    That's how bootloader section definition looks like:

    MEMORY
    {
      /** Flash start address for the bootloader. This setting will also be stored in UICR to allow the
       *  MBR to init the bootloader when starting the system. This value must correspond to
       *  BOOTLOADER_REGION_START found in dfu_types.h. The system is prevented from starting up if
       *  those values do not match. The check is performed in main.c, see
       *  APP_ERROR_CHECK_BOOL(*((uint32_t *)NRF_UICR_BOOT_START_ADDRESS) == BOOTLOADER_REGION_START);
       */
      FLASH (rx) : ORIGIN = 0x75000, LENGTH = 0x9000
    
      /** RAM Region for bootloader. This setting is suitable when used with s132. */
      RAM (rwx) :  ORIGIN = 0x20002C00, LENGTH = 0x5380
    
      /** Location of non initialized RAM. Non initialized RAM is used for exchanging bond information
       *  from application to bootloader when using buttonluss DFU OTA.
       */
      NOINIT (rwx) :  ORIGIN = 0x20007F80, LENGTH = 0x80
    
      /** Location of bootloader setting in flash. */
      BOOTLOADER_SETTINGS (rw) : ORIGIN = 0x0007F000, LENGTH = 0x1000
    
      /** Location in UICR where bootloader start address is stored. */
      UICR_BOOTLOADER (r) : ORIGIN = 0x10001014, LENGTH = 0x04
    
      /** Location of mbr params page in flash. */
      MBR_PARAMS_PAGE (rw) : ORIGIN = 0x0007E000, LENGTH = 0x1000
    
      /** Location in UICR where mbr params page address is stored. */
      UICR_MBR_PARAM_PAGE(r) : ORIGIN = 0x10001018, LENGTH = 0x04
    }
    
    SECTIONS
    {
      /* Place the bootloader settings page in flash. */
      .bootloaderSettings(NOLOAD) :
      {
    
      } > BOOTLOADER_SETTINGS
    
      /* Write the bootloader address in UICR. */
      .uicrBootStartAddress :
      {
        KEEP(*(.uicrBootStartAddress))
      } > UICR_BOOTLOADER
    
      /* Place the mbr params page in flash. */
        .mbrParamsPage(NOLOAD) :
      {
    
      } > MBR_PARAMS_PAGE
    
      /* Write the bootloader address in UICR. */
      .uicrMbrParamsPageAddress :
      {
        KEEP(*(.uicrMbrParamsPageAddress))
      } > UICR_MBR_PARAM_PAGE
    
      /* No init RAM section in bootloader. Used for bond information exchange. */
      .noinit(NOLOAD) :
      {
    
      } > NOINIT
      /* other placements follow here... */
    }
    

    note the .bootloaderSettings section. I'm no expert in gcc linker files but it seems ok. Now take a look at buttonless_dfu example .ld file:

    /* Linker script to configure memory regions. */
    
    SEARCH_DIR(.)
    GROUP(-lgcc -lc -lnosys)
    
    MEMORY
    {
      FLASH (rx) : ORIGIN = 0x1f000, LENGTH = 0x61000
      RAM (rwx) :  ORIGIN = 0x20002128, LENGTH = 0xded8
    }
    
    SECTIONS
    {
      .fs_data :
      {
        PROVIDE(__start_fs_data = .);
        KEEP(*(.fs_data))
        PROVIDE(__stop_fs_data = .);
      } > RAM
    } INSERT AFTER .data;
    
    INCLUDE "nrf5x_common.ld"
    

    note that there's no .bootloaderSettings here nor in nrf5x_common.ld.

  • Thanks, the solution works :). I'll dig in deep to find out why this wasn't happening in previous SDKs.

  • @keton: You are correct, the bootloaders settings section is missing from the linker script. I'øll make sure that this is posted under the SDK v12.0.0 Known Issues thread. Thanks for finding this :)

Related