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 

  • 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);
    }

  • Hi Akshay, 

    Please show exactly what you did in step 2. Use Insert -> Code when you want to add code to your answer. 


    Please make sure you managed to step into the code of the bootloader for debugging. You need to compile the bootloader in debug mode (no optimization , use the debug variant). You are doing something quite advanced so you need to study the bootloader code and know how to debug it. 

    With my solution what you need to do is to initialize softdevice, after that call sd_softdevice_vector_table_base_set(0xD8000 ) then call nrf_bootloader_app_start_final(0xD8000). You can try adding it to ble_dfu_transport_init() just for the shake of testing: 

  • i called here 

    ret_code_t nrf_bootloader_init(nrf_dfu_observer_t observer)
    {
    NRF_LOG_DEBUG("In nrf_bootloader_init");

    ret_code_t ret_val;
    nrf_bootloader_fw_activation_result_t activation_result;
    uint32_t initial_timeout;
    bool dfu_enter = false;

    m_user_observer = observer;

    if (NRF_BL_DEBUG_PORT_DISABLE)
    {
    nrf_bootloader_debug_port_disable();
    }

    #if NRF_BL_DFU_ENTER_METHOD_BUTTON
    dfu_enter_button_init();
    #endif

    ret_val = nrf_dfu_settings_init(false);
    if (ret_val != NRF_SUCCESS)
    {
    return NRF_ERROR_INTERNAL;
    }

    #if NRF_BL_DFU_ALLOW_UPDATE_FROM_APP
    // Postvalidate if DFU has signaled that update is ready.
    if (s_dfu_settings.bank_current == NRF_DFU_CURRENT_BANK_1)
    {
    postvalidate();
    }
    #endif
    ble_stack_init();
    sd_softdevice_vector_table_base_set(0xD8000);
    nrf_bootloader_app_start_final(0xD8000);

    //// Check if an update needs to be activated and activate it.
    //activation_result = nrf_bootloader_fw_activate();

    //switch (activation_result)
    //{
    // case ACTIVATION_NONE:
    // initial_timeout = NRF_BOOTLOADER_MS_TO_TICKS(NRF_BL_DFU_INACTIVITY_TIMEOUT_MS);
    // dfu_enter = dfu_enter_check();
    // break;

    // case ACTIVATION_SUCCESS_EXPECT_ADDITIONAL_UPDATE:
    // initial_timeout = NRF_BOOTLOADER_MS_TO_TICKS(NRF_BL_DFU_CONTINUATION_TIMEOUT_MS);
    // dfu_enter = true;
    // break;

    // case ACTIVATION_SUCCESS:
    // bootloader_reset(true);
    // NRF_LOG_ERROR("Unreachable");
    // return NRF_ERROR_INTERNAL; // Should not reach this.

    // case ACTIVATION_ERROR:
    // default:
    // return NRF_ERROR_INTERNAL;
    //}

    this is the error coming

    <info> app: Inside main

    <debug> app: In nrf_bootloader_init

    <debug> nrf_dfu_settings: Calling nrf_dfu_settings_init()...

    <debug> nrf_dfu_flash: Initializing nrf_fstorage_nvmc backend.

    <debug> nrf_dfu_settings: Using settings page.

    <debug> nrf_dfu_settings: Copying forbidden parts from backup page.

    <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.

    <info> nrf_dfu_settings: Backing up settings page to address 0xFE000.

    <debug> nrf_dfu_settings: Destination settings are identical to source, write not needed. Skipping.

    <debug> app: Enter nrf_bootloader_fw_activate

    <info> app: No firmware to activate.

    <debug> nrf_dfu_validation: CRC check of app failed. Return 1

    <debug> app: App is valid

    <debug> nrf_dfu_ble: Setting up vector table: 0x000F1000

    <debug> nrf_dfu_ble: Enabling SoftDevice.

    <debug> nrf_dfu_ble: Configuring BLE stack.

    <debug> nrf_dfu_ble: Enabling the BLE stack.

    <error> app: Received a fault! id: 0x00001001, pc: 0x000F4C7E, info: 0x40000000

  • by changing to this it is able to boot to the specific location D8000

    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(addr);
    nrf_dfu_mbr_irq_forward_address_set(MBR_SIZE);
    nrf_bootloader_app_start_final(addr);

    but now our issue is how to create a setting file using nrfutil for 2 applications for merging app1+app2+sd+bl or should i use only one application to create settings ?

Related