Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

NRF52840 Application boots from different flash address

Hi,

   In my project i need to include two different applications(one without soft device and and one with soft device) and a bootloader(secure ble) with nRF 5 SDK 17.1.0.

   Application1 START ADDRESS : 0x27000.

   Application2 START ADDRESS : 0xD8000.

   Bootloader  START ADDRESS : 0xF3000.

   Softdevice  START ADDRESS : 0x1000.

   1.I need to switch between application1 or application 2 from boootloader.How can we do this?.

   2.Is it possible to switch from app1 to app2 or vice versa?.

   we followed this link but it didn't helped. https://devzone.nordicsemi.com/f/nordic-q-a/85074/how-to-change-the-mbr-jump-address-location?pifragment-684=2 

Parents
  • H Akshay, 

    Have you tried to follow what Einar suggested ? What have you achieved ? 

    Have you tried to make your own nrf_dfu_mbr_irq_forward_address_set() where you point the address to 0xD8000 and then call nrf_bootloader_app_start_final(0xD8000)  ? 

    Another option is to use softdevice forwarding instead of the MBR. So first you need to initialize the softdevice (ble_stack_init() it should be called by default if you use BLE DFU), then you need to call sd_softdevice_vector_table_base_set(0xD8000 ) to forward the interrupt vector table, then jump to the application using nrf_bootloader_app_start_final(0xD8000)

  • what we did was is

    1.Created one ble_blinky example with start address = 0xd8000 size 0xA000.

    2.Changed the secure bootloader accroding to what you mention in the link.

    3.combined these two hex files with soft device hex (using mergehex tool) and then flashed on the dev kit but it didn't booted.

    can you explain the exact code to be written befor calling nrf_bootloader_app_start_final(0xD8000);

    currently this the the code im running in the secure bootloader

    void nrf_bootloader_app_start(uint32_t start_addr)
    {
    NRF_LOG_DEBUG("Running nrf_bootloader_app_start with address: 0x%08x", start_addr);
    uint32_t err_code;

    //NRF_LOG_INFO("Initializing SD in mbr");
    err_code = nrf_dfu_mbr_init_sd();
    if (err_code != NRF_SUCCESS)
    {
    NRF_LOG_ERROR("Failed running nrf_dfu_mbr_init_sd");
    return;
    }

    // Disable and clear interrupts
    NRF_LOG_DEBUG("Disabling interrupts");

    NVIC->ICER[0]=0xFFFFFFFF;
    NVIC->ICPR[0]=0xFFFFFFFF;
    #if defined(__NRF_NVIC_ISER_COUNT) && __NRF_NVIC_ISER_COUNT == 2
    NVIC->ICER[1]=0xFFFFFFFF;
    NVIC->ICPR[1]=0xFFFFFFFF;
    #endif

    // Set the sd softdevice vector table base address
    NRF_LOG_DEBUG("Setting SD vector table base: 0x%08x", start_addr);
    err_code = sd_softdevice_vector_table_base_set(start_addr);
    if (err_code != NRF_SUCCESS)
    {
    NRF_LOG_ERROR("Failed running sd_softdevice_vector_table_base_set");
    return;
    }
    NRF_LOG_FLUSH();
    nrf_bootloader_app_start_final(start_addr);
    }

  • Can i use the same gpgret register for switching between app1 and ap2 (0xB0 to go to app1 and 0xB2 to go to app2 ) .Any way this register is used to switch to OTA mode using 0xB1.

  • Hi Akshay, 
    No I don't see any problem doing that. You just need to implement the code in the bootloader to choose which application to jump to. 

  • Hi hung ,

                  we have one more issue where our App2 is a radio test example(pca10112) which from bootloader it is jumping to App2 but it is stuck at    app_timer_init(); -> NRF_ATFIFO_INIT(m_req_fifo); there is no return its just stuck inside this function.

    but i tried on uart peripheral example and also blinky ble example as app2 both  worked but on radio test example it is failing.

    and code i used to jump is :-

    if((nrf_power_gpregret_get() & SWITCH_APPLICATION2)==SWITCH_APPLICATION2){
    NRF_LOG_DEBUG("APP 2 0xD8000.");
    start_app_without_sd(0xD8000);
    }else{
    NRF_LOG_DEBUG("APP 1 0x27000.");
    start_app_with_sd(0x27000);
    }

    void start_app_with_sd(uint32_t startAddress)
    {
    nrf_dfu_mbr_init_sd();

    // Disable and clear interrupts
    NVIC->ICER[0] = 0xFFFFFFFF;
    NVIC->ICPR[0] = 0xFFFFFFFF;
    NVIC->ICER[1] = 0xFFFFFFFF;
    NVIC->ICPR[1] = 0xFFFFFFFF;

    sd_softdevice_vector_table_base_set(startAddress);
    nrf_dfu_mbr_irq_forward_address_set(MBR_SIZE);
    nrf_bootloader_app_start_final(startAddress);
    }

    void start_app_without_sd(uint32_t startAddress)
    {
    NVIC->ICER[0] = 0xFFFFFFFF;
    NVIC->ICPR[0] = 0xFFFFFFFF;
    NVIC->ICER[1] = 0xFFFFFFFF;
    NVIC->ICPR[1] = 0xFFFFFFFF;

    nrf_dfu_mbr_irq_forward_address_set(startAddress);
    nrf_bootloader_app_start_final(startAddress);
    }

      

  • Hi Akshay, 

    As mentioned in the previous reply, please re-post the code with Insert -> code.I can't read your code like that.

    I think it's because interrupt forwarding was not correct. The blinky doesn't use any interrupt when the radio test does use. 

    I think if you don't wan to update the radio test firmware, an easier way to do this is to integrate the radio test into the bootloader. You can perform radio test inside the bootloader if you want. 

  •  else
        {
            NRF_POWER->TASKS_CONSTLAT = 0;
    
            // Erase additional data like peer data or advertisement name
            ret_val = nrf_dfu_settings_additional_erase();
            if (ret_val != NRF_SUCCESS)
            {
                return NRF_ERROR_INTERNAL;
            }
    
            m_flash_write_done = false;
            nrf_dfu_settings_backup(flash_write_callback);
            ASSERT(m_flash_write_done);
    
            //uint32_t appSwitchCheck = nrf_power_gpregret_get();
            if((nrf_power_gpregret_get() & SWITCH_APPLICATION2)==SWITCH_APPLICATION2){
              NRF_LOG_DEBUG("APP 2 0xD8000.");
              start_app_without_sd(0xD8000);
            }else{
              NRF_LOG_DEBUG("APP 1 0x27000.");
              start_app_with_sd(0x27000);
            }
            //nrf_bootloader_app_start();
            NRF_LOG_ERROR("Unreachable");
        }
        
        void start_app_with_sd(uint32_t startAddress)
    {
        nrf_dfu_mbr_init_sd();
    
        // Disable and clear interrupts
        NVIC->ICER[0] = 0xFFFFFFFF;
        NVIC->ICPR[0] = 0xFFFFFFFF;
        NVIC->ICER[1] = 0xFFFFFFFF;
        NVIC->ICPR[1] = 0xFFFFFFFF;
    
        sd_softdevice_vector_table_base_set(startAddress);
        nrf_dfu_mbr_irq_forward_address_set(MBR_SIZE);
        nrf_bootloader_app_start_final(startAddress);
    }
    
    void start_app_without_sd(uint32_t startAddress)
    {
        NVIC->ICER[0] = 0xFFFFFFFF;
        NVIC->ICPR[0] = 0xFFFFFFFF;
        NVIC->ICER[1] = 0xFFFFFFFF;
        NVIC->ICPR[1] = 0xFFFFFFFF;
    
        nrf_dfu_mbr_irq_forward_address_set(startAddress);
        nrf_bootloader_app_start_final(startAddress);
    }
        
        
        
        

Reply
  •  else
        {
            NRF_POWER->TASKS_CONSTLAT = 0;
    
            // Erase additional data like peer data or advertisement name
            ret_val = nrf_dfu_settings_additional_erase();
            if (ret_val != NRF_SUCCESS)
            {
                return NRF_ERROR_INTERNAL;
            }
    
            m_flash_write_done = false;
            nrf_dfu_settings_backup(flash_write_callback);
            ASSERT(m_flash_write_done);
    
            //uint32_t appSwitchCheck = nrf_power_gpregret_get();
            if((nrf_power_gpregret_get() & SWITCH_APPLICATION2)==SWITCH_APPLICATION2){
              NRF_LOG_DEBUG("APP 2 0xD8000.");
              start_app_without_sd(0xD8000);
            }else{
              NRF_LOG_DEBUG("APP 1 0x27000.");
              start_app_with_sd(0x27000);
            }
            //nrf_bootloader_app_start();
            NRF_LOG_ERROR("Unreachable");
        }
        
        void start_app_with_sd(uint32_t startAddress)
    {
        nrf_dfu_mbr_init_sd();
    
        // Disable and clear interrupts
        NVIC->ICER[0] = 0xFFFFFFFF;
        NVIC->ICPR[0] = 0xFFFFFFFF;
        NVIC->ICER[1] = 0xFFFFFFFF;
        NVIC->ICPR[1] = 0xFFFFFFFF;
    
        sd_softdevice_vector_table_base_set(startAddress);
        nrf_dfu_mbr_irq_forward_address_set(MBR_SIZE);
        nrf_bootloader_app_start_final(startAddress);
    }
    
    void start_app_without_sd(uint32_t startAddress)
    {
        NVIC->ICER[0] = 0xFFFFFFFF;
        NVIC->ICPR[0] = 0xFFFFFFFF;
        NVIC->ICER[1] = 0xFFFFFFFF;
        NVIC->ICPR[1] = 0xFFFFFFFF;
    
        nrf_dfu_mbr_irq_forward_address_set(startAddress);
        nrf_bootloader_app_start_final(startAddress);
    }
        
        
        
        

Children
Related