aboutsummaryrefslogtreecommitdiffstats
path: root/firmware
diff options
context:
space:
mode:
authorKévin Redon <kredon@sysmocom.de>2018-07-07 13:48:44 +0200
committerKévin Redon <kredon@sysmocom.de>2018-07-07 14:18:58 +0200
commit9e29a3eb37acde5ec5a63b29bdab26055a60bd80 (patch)
treed30c4ec2e48d8afbb6eca837cd78884d9ad83bab /firmware
parentbf6b1b1a3eb97c117c37644c4a7d94298db9d518 (diff)
DFU: set stack pointer before starting main app
The stack size is fixed. The linker script puts the stack section after the bss section. The initial stack pointer is not at the end of the RAM (as often seen). Thus the initial stack pointer address of the main application is different than the one from DFU. When starting the main application the stack pointer needs to be set to the new value. If this is not done the main application stack may overwrite the data in bss, even without exceeding the fixed stack size. Change-Id: Ie354d603fe302d3d5bdfa9c31575411de722323b
Diffstat (limited to 'firmware')
-rw-r--r--firmware/libboard/common/source/board_cstartup_gnu.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/firmware/libboard/common/source/board_cstartup_gnu.c b/firmware/libboard/common/source/board_cstartup_gnu.c
index 15c70dd..4b561ec 100644
--- a/firmware/libboard/common/source/board_cstartup_gnu.c
+++ b/firmware/libboard/common/source/board_cstartup_gnu.c
@@ -133,7 +133,11 @@ static void BootIntoApp(void)
void (*appReset)(void);
pSrc = (unsigned int *) ((unsigned char *)IFLASH_ADDR + BOARD_DFU_BOOT_SIZE);
- SCB->VTOR = ((unsigned int)(pSrc)) | (0x0 << 7);
+ /* set vector table to application vector table (store at the beginning of the application) */
+ SCB->VTOR = (unsigned int)(pSrc);
+ /* set stack pointer to address provided in the beginning of the application (loaded into a register first) */
+ __asm__ volatile ("MSR msp,%0" : :"r"(*pSrc));
+ /* start application (by jumping to the reset function which address is stored as second entry of the vector table) */
appReset = (void(*)(void))pSrc[1];
g_dfu->state = DFU_STATE_appIDLE;