I want to move my code in the flash memory on an STM32F405.
I changed the linker script to change the start of flash like so:
FLASH (rx) : ORIGIN = 0x08008000, LENGTH = 1024K-32K
If I am correct the vector table will also be located at 0x08008000. I would like to create a bootloader for a start I would like to run my application in the new memory location. Do my bootloader and application have sepperate vector tables? How can I initialize the stack pointer to 0x8008000?
Yes, your bootloader will have a separate vector table to your main code. The last thing your bootloader, or the first thing your main code should do is remap the vector table, using the SCB->VTOR
register. The vector table is 4 bytes in from the start of the image, so using your numbers, SCB->VTOR
should be 0x08008004. The first 4 bytes of the image are the value the stack pointer should be initialised with.
You don't want to initalise your stack pointer to 0x8008000, that address is in flash and will cause a hard fault as soon as you try to push something, if that is where your application starts then the memory at 0x08008000 contains the address you should use as the stack pointer.
To set it I have always used an asm function which just loads SP
with the value passed to the function in R0
, something like the following.
SetSP PROC
EXPORT SetSP
MOV SP, R0
BX LR
ENDP
To call from a C context:
extern void SetSP(uint32_t address);
uint32_t sp = *((uint32_t *)0x08008000);
SetSP(sp);
That dereferences a pointer to 0x08008000, to get the initial stack pointer, then sets it.