This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Problem relocating vector start from bootloader to application

I am using IAR workbench. Using softdevice s110 Version 7. I have created a bootloader at memory address 0x3A000. My application sits at 0x16000. My application checks on startup if the UICR bootadress at 10001014 is written to 0x3A000. If it is not, it writes the bootadress

After the first startup, the uicr bootadress is written and the mbr now always starts my bootloader code at 0x3A000. The bootloader then checks if the application is present and CRC is correct. If everything is correct, the application should be started.

To do so I first disable all interrupts using this code:

static void interrupts_disable(void)
{
    uint32_t interrupt_setting_mask;
    uint32_t irq = 0; // We start from first interrupt, i.e. interrupt 0.

    // Fetch the current interrupt settings.
    interrupt_setting_mask = NVIC->ISER[0];

    for (; irq < MAX_NUMBER_INTERRUPTS; irq++)
    {
        if (interrupt_setting_mask & (IRQ_ENABLED << irq))
        {
            // The interrupt was enabled, and hence disable it.
            NVIC_DisableIRQ((IRQn_Type)irq);
        }
    }
}

Next i want to set the interrupt vector to my application and use the following call: sd_softdevice_vector_table_base_set(0x16000);

If I have understood everything correctly, this should provoke a SVC call which is handeld by the MBR which sets the vector to 0x16000 overriding the address in UICR Bootaddress. This is where things go wrong. The software restarts and the bootloaders starts its code again.

Stepping through my dissassembly window i notice that when i call the sd_softdevice_vector_table_base_set function, my source jumps to 0x6b0, which is probably the svc handler in the MBR. after a couple of instructions it now jumps to my application code (not the bootloader), and then back again to the mbr at address 0x6d2 and then after a few instructions in the mbr ending at 0x71c, the Reset Handler at 0x3b308 is called:

       MOVS    R1, #NRF_POWER_RAMONx_RAMxON_ONMODE_Msk
        
        LDR     R0, =NRF_POWER_RAMON_ADDRESS
        LDR     R2, [R0]
        ORRS    R2, R2, R1
        STR     R2, [R0]
        
        LDR     R0, =NRF_POWER_RAMONB_ADDRESS
        LDR     R2, [R0]
        ORRS    R2, R2, R1
        STR     R2, [R0]
        
        LDR     R0, =SystemInit
        BLX     R0
        LDR     R0, =__iar_program_start
        BX      R0
        ;
(defined by Iar)

When I do not try to change the vector address, and jump to my application, the application crashes as soon as it starts softdevice. When UICR is not set and the bootloader is not started, the application works correctly at 0x16000 and all bluetooth functions are functioning correctly. I can't seem to figure out what I am doing wrong here. How do I tell mbr to ignore UICR and use my application vector instead? Where does the MBR store the new vector address? is it in ram or flash? Shouldn't the mbr handle the SVC call instead of forwarding to the application ?

Parents
  • Hi R. Schultze,

    You would need to initialize the softdevice before you can call sd_softdevice_vector_table_base_set(). This call only tell the softdevice not the MBR to forward the interrupt vector table to the specified address.

    I have some explanation on how the vector table is forwarded with the MBR, Softdevice and bootloader here, at section B.

Reply
  • Hi R. Schultze,

    You would need to initialize the softdevice before you can call sd_softdevice_vector_table_base_set(). This call only tell the softdevice not the MBR to forward the interrupt vector table to the specified address.

    I have some explanation on how the vector table is forwarded with the MBR, Softdevice and bootloader here, at section B.

Children
No Data
Related