MCU boot-up sequence question
Ok, I figured what was going on and why it was going on.
Following was in the programming manual PM0214
Stack pointer
The Stack Pointer (SP) is register R13. In Thread mode, bit1 of the CONTROL register
indicates the stack pointer to use:
• 0 = Main Stack Pointer (MSP). This is the reset value.
• 1 = Process Stack Pointer (PSP).
On reset, the processor loads the MSP with the value from address 0x00000000.
Link register
The Link Register (LR) is register R14. It stores the return information for subroutines,
function calls, and exceptions. On reset, the processor loads the LR value 0xFFFFFFFF.
Program counter
The Program Counter (PC) is register R15. It contains the current program address. Bit0 is
always 0 because instruction fetches must be halfword aligned. On reset, the processor
loads the PC with the value of the reset vector, which is at address 0x00000004.
This made me very confused at first, because I had done a chip erase and the adr, 0x0800 0000, onto which the 0x0000 0000 address is aliased to in normal boot didn’t contain anything else except 0xFFFF FFFF. “Well how the heck is the MCU then booting to 0x0800 8000, where my application is?”. I had only used the openocd debugger in AC6 when testing my application until this point, so I decided to just use the ST-LINK UTILITY, because I know that it doesn’t do anything else except write the .bin file contents to the chosen memory address. So I then proceeded to do a chip erase and then write the application’s .bin file to the 0x0800 8000 address. Application doesn’t run now... what?
Turns out running the debugger in AC6 jumps itself to the 0x0800 8000 and that’s why it begins running the app no problem and why my other apps in the FLASH didn’t confuse it. But testing this through the ST-LINK UTILITY showed that writing the .bin on a erased chip to either 0x0800 0000 or 0x0800 8000 yielded no running code but writing to both addresses did... What?
Actually it makes very much sense after thinking about it.
If the app is only written to the 0x0800 0000 it begins running, but the reset handler then jumps to 0x0800 8000 area, which contains no running code and therefore hangs.
If the app is only written to the 0x0800 8000 then it won’t ever be run because as the code execution starts from the 0x0800 0000, which now only contains invalid instructions and hangs.
But if it’s written in both places then it will jump from 0x0800 0000 to the 0x0800 8000, which now does contain running code and goes happily running on it’s way.
TLDR: Code running starts from (in this case) 0x0800 0000, but AC6 debugger jumped automatically to 0x0800 8000 at the start of debugging.