cancel
Showing results for 
Search instead for 
Did you mean: 

Can initial stack pointer change the program behaviour with bootloader?

sx107
Associate

So, I am trying to use this USB mass storage bootloader: https://github.com/sfyip/STM32F103_MSD_BOOTLOADER

To compile .hex files for it, I've already set the flash origin to 0x8004000 and the vector table offset to the same value. I've verified that, indeed, the generated hex file starts at 0x8004000 and through debug I've verified that SCB->VTOR is the right value. However, I still could run a simple blink app only from the debug from STM32CubeIDE - when I uploaded the firmware to the 0x8004000 address either via ST-link or via the bootloader, the blink did not work.

However, I then took a look at the example hex file of a blink project the bootloader creator provides. Here I saw that the first value of the hex file is 0x20000408 - the initial stack pointer value, if I understand everything correctly. In the bootloader hex itself, the initial stack pointer value is 0x20001250 (compiled with keil uVision 5). However, in all applications I compile from Stm32CubeIDE that I use, the value is 0x20005000. That is when I started to edit my hex files and play with it.

What I discovered is that any values lower than 0x20005000 - I've tried 0x20000408, 0x20002000, 0x20003000, 0x20004000 and even 0x20004999 - do work, they successfully upload to the microcontroller both with ST-link and the bootloader. The bootloader flawlessly jumps to the main application and the blinking starts. But with any values equal or larger than 0x20005000, the application does not work.

The jump to main application in the bootloader is performed with this code, where APP_ADDR is 0x8004000:

  uint32_t jump_addr = *((__IO uint32_t*)(APP_ADDR+4u));
  HAL_DeInit();
  /* Change the main stack pointer. */
  __set_MSP(*(__IO uint32_t*)APP_ADDR);
  SCB->VTOR = APP_ADDR;
  ((void (*) (void)) (jump_addr)) (); 
 
 

Everything seems fine, the MSP is set according to the hex file (0x20005000), Vector offset is set to 0x8004000 (which is set again in my app in SystemInit()) and the jump is performed.

  1. What is going on here, why can't I set initial stack pointer to 0x20005000?
  2. Am I breaking something by changing it? Will apps more complex than blink() work?
  3. Could the problem be related to the fact that the bootloader is compiled with Keil uVision, while I use Stm32CubeIDE? Perhaps, different linker settings? If so, what do I need to change in the keil uVision linker?
  4. If I do need to set the initial stack pointer to another value, how do I do it in Stm32CubeIDE, not by modifying the .hex file?
  5. Could this issue be common for all bootloaders?
  6. Am I even on the right track, or the issue is deeper than I think?

1 REPLY 1
Bubbles
ST Employee

Hello @sx107​ ,

there are vast differences within F103 line, with SRAM size ranging from 6 to 96kB. You probably have 20kB device where the 0x20005000 is not physically available, while 0x20004F00 is fine.

BR,

J

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.