Search code examples
carmlinker-scriptsstm32f4

moving the vector table on an STM32F405


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?


Solution

  • 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.