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 ?