I have an stm32f303 discovery board, and I'm trying to understand the linking and relocating process more. I'm compiling and running this example here: https://github.com/mblythe86/stm32f3-discovery-basic-template
The reset stack pointer value is defined in the vector table in the setup script Device/startup_stm32f30x.s. The original value is 0x2000A000 (ie. initial SRAM address + 32K). The only other things I can see that are allocated to the SRAM are the .data and .bss sections:
2 .data 0000004c 20000000 08000e94 00020000 2**2
CONTENTS, ALLOC, LOAD, DATA
3 .bss 00000040 2000004c 08000ee0 0002004c 2**2
ALLOC
So (ignoring the stack) everything from address 0x2000008c - 0x40000000 should be free for me to use as far as SRAM is concerned?
I try decreasing the initial stack pointer value by 32 bytes (from 0x2000A000 to 0x20009FD0) in the startup script and we compile and run everything fine.
I try increasing the initial stack pointer value by 32 bytes (from 0x2000A000 to 0x2000A020) and things stop working.
Running GDB and breaking at the SystemInit function, the disassembly that is causing the problem looks like:
08000c18 <SystemInit>:
8000c18: b580 push {r7, lr}
8000c1a: af00 add r7, sp, #0
8000c1c: 4a1f ldr r2, [pc, #124] ; (8000c9c <SystemInit+0x84>)
8000c1e: 4b1f ldr r3, [pc, #124] ; (8000c9c <SystemInit+0x84>)
8000c20: f8d3 3088 ldr.w r3, [r3, #136] ; 0x88
at which point we trigger an exception of some kind and jump to WWDG_IRQHandler
. The value of r3 at the ldr.w instruction is 0xe000ed00, which appears to be something on the peripheral device bus?
The confusing part for me is that this section of code and all of the register and memory addresses are identical in the original version that works (except for the stack pointer value, of course), including the ldr.w memory access at 0xe000ed00 + 0x88. Any idea what is going on here? Is there something else managing the initial stack pointer besides the vector table?
My advices.
Download a bit more user friendly IDE with decent debugger GUI. For example atollic studio.
Stop using found somewhere on the net "templates". This one uses prehistoric SPL library - not supported any more by STM. Use CubeMx to generate the project templates.
you have 48k of RAM but divided into two different memory areas. 40k SRAM(0x20000000 - 0x2000A000) and CCM RAM (0x10000000 - 0x10002000)
As per point 3. the last address of the SRAM is 0x2000A000 so when you place the stack at 0x2000A020 - you instantly end up in the HardHault handler. (It is not WDG as in your startup all HFs are handled by one function)
You can also place the stack in the CCM RAM.
This is the simplest configuration - ARM cores have 2 stacks used by the user and the privileged code.
Stack does not have to be at the end of the memory area. I often prevere to place it at the beginning. When the stack overflows it invokes the HF giving me the chance to take action. If stack is at the end of the RAM it may silently overflow overwriting the data stored in RAM
Always read the full documentation. Datasheet, Reference manual & programming manual