2020-03-04 09:47 AM
Hi all, I'm usina a STM32F479 MCU and I'm tryng to build a software that can write and launch another software located in flash memory.
The idea is that my main program (that handles the update and lanches the other program) shall be located in flash memory at address 0x08000000 (where the MCU starts executing code at power-on) and my child program shall be located at 0x08010000.
Let's call them program A (the main one) and B (the child).
Reading the manual and visiting other posts on the forum I understand that I need to relocate the interrupt vector table, so, in the main() of A i wrote:
int main()
{
SCB->VTOR = 0x08010000; //--relocate interrupt vector tabl
callMainOfProgramB(); //-- Function to jump to 0x08010000
}
In addition to this, i edited the linker script file of A and B with the following:
A: flash starts at 0x08000000, size: 64K
B: flash starts at 0x08010000, size 1984K
The only problem is that if I flash them both at those addresses (I double checked the programming and the memory with STM32CubeProg), I get an hard fault, type Usage fault (INVSTATE) after the jump. The program actually jumps, but there could be something wrong with the code where it jumps to. I don't know what...
Am I missing something? are there other passages that I missed?
Thanks for the help in advance.
2020-03-04 11:19 AM
This is called a bootloader. Now when you know what to search for, please google ;)
Correctly implement "callMainOfProgramB".
-- pa
2020-03-04 12:37 PM
The vector table isn't executable code, it is a table of addresses which point to executable code.
The address of 16-bit THUMB code is ODD (A0=1), the CM4 will hard fault if the address is EVEN (A0=0)
Perhaps review some IAP (In-App Programming) examples, and technical materials on the CM4 MCU
2020-03-05 12:59 AM
Thanks for answering.
I managed to solve the problem and now my program B is working.
I have B with VECT_TAB_OFFSET defined to 0x08010000, and the .ld file with FLASH starting at 0x08010000.
I implemented callMainOfProgramB() like this:
typedef void (*f_ptr)(void);
void callMainOfProgramB()
{
uint32_t address = *(__IO uint32_t*)(0x08010000 + 4);
f_ptr launchB = (f_ptr) address;
launchB();
}
void main() //-- program A
{
HAL_Init();
SystemClock_Config();
callMainOfProgramB();
}
2020-03-12 12:05 AM
There is a much better and simpler approach described in my comment there: