I've got a question. I'm developing an IAP (In-Application Programming) tool for my STM32F446RE board and I'm stuck. I've developed all the necessary utilities in order to let to the microcontroller to receive a binary (.bin) compiled file from a GUI, write it on a specific flash memory sector and execute it. My problem comes when, from the uploaded code, I want to jump again to the bootloader that is stored on the flash memory sector 0, I see that the code does not jump to the bootloader but, instead, it continues the execution of the user application code. I've debugged the code and I seen that all the addresses (the msp and the reset handler) of the bootloader code are correctly set and they are different compared to the ones of the uploaded code.
The flow that i want to achieve is the following:
1 --> Execute the bootloader code stored on sector 0 (starting at address 0x0800 0000, when an interrupt from the User button is received) and write the newly received code into the sector 2 (starting at address 0x0800 8000)
2 --> set the msp address (@0x0800 8000) and the reset handler address (0x0800 8004)
3 --> jump to the reset handler address of the new code (@0x0800 8004)
4 --> execute the new uploaded code.
5 --> during the user code execution, if an interrupt is received (from user push button) then set the bootloader msp address, the reset handler and jump to the bootloader
6 --> repeat again from step one.
This is the code used to jump from the bootloader to the user application:
IAP_loadProgram(&data);
//pointer to the user application reset handler address
void (*user_resetHandler)(void);
//set the user application MSP address (user application starts on the flash SECTOR2
uint32_t msp_addr = *(volatile uint32_t *)APPLICATION_ADDRESS;
__set_MSP(msp_addr);
//Set now the addres of the reset handler
uint32_t resetAddr = *(volatile uint32_t *)(APPLICATION_ADDRESS + 4);
user_resetHandler = (void *)resetAddr;
//When there, the bootloader sector will be leaved and the user code execution starts
user_resetHandler();
Finally, the code used to jump from the user application code to the bootloader is:
if(toBootloader){
toBootloader = 0;
//pointer to the user application reset handler address
void (*bootLoader_resetHandler)(void);
//set the user application MSP address (user application starts on the flash SECTOR2
uint32_t msp_addr = *(volatile uint32_t *)BOOTLOADER_ADDRESS;
__set_MSP(msp_addr);
//Set now the address of the reset handler
uint32_t bootLoaderResetAddr = *(volatile uint32_t *)(BOOTLOADER_ADDRESS + 4);
bootLoader_resetHandler = (void *)bootLoaderResetAddr;
//When there, the user code sector will be leaved and the bootloader code execution starts
bootLoader_resetHandler();
}
Where APPLICATION_ADDRESS is 0x0800 8000 and BOOTLOADER_ADDRESS is 0x0800 0000.
The content of the first two addresses of the bootloader code is:
0x08000000: 20020000
0x08000004: 080044DD
meanwhile the content of the first two addresses of the application code is:
0x08008000: 20020000
0x08008004: 0800A1F1
Last modify that i've done is on the user application linker (.ld) file, where i set the flash start to the address 0x0800 8000 (instead of the address 0x0800 0000).
All the interrupts are correctly working and, after that the code has been uploaded, if I do a hardware reset, the result is the same, the code execution starts from the user application code, not from the bootloader. Any tips?