So, I am trying to use this USB mass storage bootloader for the STM32F103C8 (64kB flash): 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 (in RAM space), 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 the value 0x20005000, the application does not work (larger values obviously don't work since they are beneath the RAM space). During debug I discovered that with 0x20005000 value the microcontroller jumps into the hard fault handler, with 0x20004999 it does not.
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.
- What is going on here, why can't I set initial stack pointer to 0x20005000?
- Am I breaking something by changing it? Will apps more complex than blink() work?
- 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?
- 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?
- Could this issue be common for all bootloaders?
- Am I even on the right track, or the issue is deeper than I think?