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

nrfConnect Programmer Error with DFU Bootloader and Softdevice

I'm unable to program a nrf52840 dev kit (BMD340 dev kit) using the attached hex file combination of Bootloader and softdevice. Both bootloader and softdevice can be programmed individually but not together. 

SDK15.3

Segger Embedded Studio 4.18 as the IDE + compilation environment

I have tried both nrfGoStudio and the new nrfConnect Programmer app. nrfGoStudio throws an error about the hex files overlapping. nrfConnect throws a large number of errors, log file attached. Both the bootloader and the softdevice load just fine when I press the debug button in segger embedded studio, so this must be an error with nrfConnect Programmer app. 

Does the bootloader need to be combined with the softdevice before nrfConnect programmer will accept them? The errors in nrfConnect are pretty useless to me. 

I built the example  dfu\secure_bootloader\pca10056_ble_debug and attached the generated hexfile. 


secure_bootloader_ble_s140_pca10056_debug.hex

s140_nrf52_6.1.1_softdevice.hex

nrfConnectProgrammer-log.txt

Parents
  • Hi Eric, 

    Yes, this is a known issue in SDK v15.3.0, i.e. that the bootloader and SoftDevice( specifically the MBR) have overlapping sections. In this SDK version we are placing the bootloader start address and the MBR parameter page address in the MBR region. Hence,  Programming the generated bootloader hex file with nrfjprog using the --sectorerase command after the SoftDevice has been programmed or vice versa, this is happening under the hood in the nRF Connect Programmer app, will result in the MBR being erased as it will erase the first page(0x0000 to 0x1000). 

    This can be solved by merging the SoftDevice hex file with the bootloader hex file and then programming the combined hex. However, this is a bit cumbersome so we will likely switch to an approach where we write the bootloader start address and MBR params page address to UICR like before and then the bootloader will at run-time write the bootloader start address to the MBR page. I have implemented this in SDK v15.3.0 and it is done by modifying the uicr_bootloader_start_address and sections in the flash_placement.xml to the following

     <MemorySegment name="uicr_bootloader_start_address" start="0x10001014" size="0x4">
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".uicr_bootloader_start_address" address_symbol="__start_uicr_bootloader_start_address" end_symbol="__stop_uicr_bootloader_start_address" start = "0x10001014" size="0x4" />
      </MemorySegment>
      <MemorySegment name="uicr_mbr_params_page" start="0x10001018" size="0x4">
        <ProgramSection alignment="4" keep="Yes" load="Yes" name=".uicr_mbr_params_page" address_symbol="__start_uicr_mbr_params_page" end_symbol="__stop_uicr_mbr_params_page" start = "0x10001018" size="0x4" />
      </MemorySegment>
    </Root>

    To write the addresses to the MBR section at run time you will have to modify the following defines and add nrf_bootloader_write_bl_addr_to_mbr() to main() before nrf_bootloader_flash_protect() is used to protect the MBR and the bootloader. 

    // in nrf_mbr.h
    #define MBR_BOOTLOADER_ADDR      (0xFF8)
    #define MBR_PARAM_PAGE_ADDR      (0xFFC)
    
    //in app_util.h
    #define CODE_START ((uint32_t)&_vectors)
    
    //in nrf_bootloader_info.h
    #define BOOTLOADER_START_ADDR (CODE_START)
    
    //in nrf_dfu_types.h
    #define NRF_MBR_PARAMS_PAGE_ADDRESS         (0x0007E000UL)
    
    ret_code_t nrf_bootloader_write_bl_addr_to_mbr(void){
    
        if( (*(volatile uint32_t *)MBR_BOOTLOADER_ADDR != BOOTLOADER_START_ADDR) && 
         (*(volatile uint32_t *)MBR_PARAM_PAGE_ADDR = NRF_MBR_PARAMS_PAGE_ADDRESS))
         {
              // Enable Write with the NVMC
              NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen << NVMC_CONFIG_WEN_Pos;
              while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
    
              // Write Bootloader start address to MBR 
              *(volatile uint32_t *)MBR_BOOTLOADER_ADDR = BOOTLOADER_START_ADDR;
              // Write MBR parameter page address to MBR
              *(volatile uint32_t *)MBR_PARAM_PAGE_ADDR = NRF_MBR_PARAMS_PAGE_ADDRESS;
              // Revert NVMC to read-only
              NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren << NVMC_CONFIG_WEN_Pos;
              while (NRF_NVMC->READY == NVMC_READY_READY_Busy){}
          }
    
        return NRF_SUCCESS;
    }

    Best regards

    Bjørn

  • Thank you Bjorn,

    The changes to flash_placement.xml and the added nrf_bootloader_write_bl_addr_to_mbr appear to have worked.

    Has Nordic added this information to the DFU tutorials?

    I wasn't able to find this information by either google or searching the forums, could be I had the wrong keywords. 

    These were already defined as you stated:

    // in nrf_mbr.h
    #define MBR_BOOTLOADER_ADDR (0xFF8)
    #define MBR_PARAM_PAGE_ADDR (0xFFC)
    
    //in app_util.h
    #define CODE_START ((uint32_t)&_vectors)
    
    //in nrf_bootloader_info.h
    #define BOOTLOADER_START_ADDR (CODE_START)

    This file had a different definition for the nrf52840 (you posted the one for the 832)

    //in nrf_dfu_type.h
    #if defined(NRF52840_XXAA) || defined(NRF52840_XXAA_ENGA)
        #define NRF_MBR_PARAMS_PAGE_ADDRESS         (0x000FE000UL)
    #elif defined(NRF52832_XXAA)
        #define NRF_MBR_PARAMS_PAGE_ADDRESS         (0x0007E000UL)

Reply
  • Thank you Bjorn,

    The changes to flash_placement.xml and the added nrf_bootloader_write_bl_addr_to_mbr appear to have worked.

    Has Nordic added this information to the DFU tutorials?

    I wasn't able to find this information by either google or searching the forums, could be I had the wrong keywords. 

    These were already defined as you stated:

    // in nrf_mbr.h
    #define MBR_BOOTLOADER_ADDR (0xFF8)
    #define MBR_PARAM_PAGE_ADDR (0xFFC)
    
    //in app_util.h
    #define CODE_START ((uint32_t)&_vectors)
    
    //in nrf_bootloader_info.h
    #define BOOTLOADER_START_ADDR (CODE_START)

    This file had a different definition for the nrf52840 (you posted the one for the 832)

    //in nrf_dfu_type.h
    #if defined(NRF52840_XXAA) || defined(NRF52840_XXAA_ENGA)
        #define NRF_MBR_PARAMS_PAGE_ADDRESS         (0x000FE000UL)
    #elif defined(NRF52832_XXAA)
        #define NRF_MBR_PARAMS_PAGE_ADDRESS         (0x0007E000UL)

Children
No Data
Related