cancel
Showing results for 
Search instead for 
Did you mean: 

application jump to system memory bootloader

Schmid.M.
Senior

Hi,

I have an stm32l43 connected as a USB device. Using the BOOT0 pin, I can start the built-in Bootloader and use DFU. Now I wish to jump to the BL without this Pin by a software jump.

But with this jump, I only seem to reset the device (my code starts again like after a reset). It seems to me that the Bootloader starts, checks for valid code in flash and then streight jumps back there (as my firmware of course is valid code).

How can I get the Bootloader staying active without using a boot pin or an option bit?

here is my jump function for reference:

void jump2STinternalBootloader(void){
	void (*SysMemBootJump)(void);
 
	/**
	 * Set system memory address.
	 *       check AN2606 document for descriptions of memory addresses
	 */
	volatile uint32_t addr = 0x1FFF0000;
 
	/**
	 * Disable RCC, set it to default (after reset) settings
	 *       Internal clock, no PLL, etc.
	 */
	HAL_RCC_DeInit();
 
	/**
	 * Disable systick timer and reset it to default values
	 */
	SysTick->CTRL = 0;
	SysTick->LOAD = 0;
	SysTick->VAL = 0;
 
	/**
	 * Disable all interrupts
	 */
	__disable_irq();
 
	/**
	 * Remap system memory to address 0x0000 0000 in address space
	 */
	__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();
 
	/**
	 * Set jump memory location for system memory
	 *       Use address with 4 bytes offset which specifies jump location where program starts
	 */
	SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4)));
 
	/**
	 * Set main stack pointer.
	 *       This step must be done last otherwise local variables in this function
	 *       don't have proper value since stack pointer is located on different position
	 *
	 *       Set direct address location which specifies stack pointer in SRAM location
	 */
	__set_MSP(*(uint32_t *)addr);
 
	/**
	 * Actually call our function to jump to set location
	 *       This will start system memory execution
	 */
	SysMemBootJump();
	while(1);
}

1 ACCEPTED SOLUTION

Accepted Solutions
I have a solution now: it seems like there was still a problem in my jump function. I added stopping of FreeRTOS, stopping and de-init of USB and also a HAL_DeInit() and now it stays in Bootloader as it should. Probably there were some registers which needed to be completely de-initialized before jumping.
Thanks for your help and best regards,
Michael
void jump2STinternalBootloader(void){
void (*SysMemBootJump)(void);
volatile uint32_t addr = 0x1FFF0000;
// suspend kernel
osKernelLock();
//stop and deinit USB
USBD_Stop(&hUsbDeviceFS);
USBD_DeInit(&hUsbDeviceFS);
/**
* Disable RCC, set it to default (after reset) settings
* Internal clock, no PLL, etc.
*/
HAL_RCC_DeInit();
/**
* Disable systick timer and reset it to default values
*/
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
//reset all periphals
HAL_DeInit();
__disable_irq();
/**
* Remap system memory to address 0x0000 0000 in address space
*/
__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();
/**
* Set jump memory location for system memory
* Use address with 4 bytes offset which specifies jump location where program starts
*/
SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4)));
/**
* Set main stack pointer.
* This step must be done last otherwise local variables in this function
* don't have proper value since stack pointer is located on different position
*
* Set direct address location which specifies stack pointer in SRAM location
*/
__set_MSP(*(uint32_t *)addr);
/**
* Actually call our function to jump to set location
* This will start system memory execution
*/
SysMemBootJump();
while(1);
}

View solution in original post

10 REPLIES 10
Uwe Bonnes
Principal III

As often explained here, best way is a switch at the start of bootup, loking for some magic in some unerase RAM. To enter bootloader, set the magic and do a hard reset. Look at older threads about that in this forum.

Schmid.M.
Senior

sure, when writing my own bootloader, I used to do it this way. But i don't have influence on what the built-in Bootloader in System memory does. If there is valid code, it jumps there, no matter what magic I have done before.

TDK
Guru

> It seems to me that the Bootloader starts, checks for valid code in flash and then streight jumps back there (as my firmware of course is valid code).

That's not what the bootloader does. Why do you think it's aborting its mission?

If you feel a post has answered your question, please click "Accept as Solution".

I just watched it directly restarting after my jump-command. If there are no errors in my jump function(see above), this was the only explanation I had. If it jumps to Bootloader and then normal code execution restarts, the bootloader must have jumped back to flash (or there was a reset for some reason).

Look at RCC->CSR to find the reason for the reset.
If you feel a post has answered your question, please click "Accept as Solution".

both the RCC_FLAG_SFTRST and RCC_FLAG_PINRST flags are set...

Yes, it does this. ST has an extremely short-sighted approach, making it difficult to adapt.

You'd need to do some technical analysis, and find secondary access points, or use other methods to change the behaviour.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Schmid.M.
Senior

*edit: found solution, see above.

I have a solution now: it seems like there was still a problem in my jump function. I added stopping of FreeRTOS, stopping and de-init of USB and also a HAL_DeInit() and now it stays in Bootloader as it should. Probably there were some registers which needed to be completely de-initialized before jumping.
Thanks for your help and best regards,
Michael
void jump2STinternalBootloader(void){
void (*SysMemBootJump)(void);
volatile uint32_t addr = 0x1FFF0000;
// suspend kernel
osKernelLock();
//stop and deinit USB
USBD_Stop(&hUsbDeviceFS);
USBD_DeInit(&hUsbDeviceFS);
/**
* Disable RCC, set it to default (after reset) settings
* Internal clock, no PLL, etc.
*/
HAL_RCC_DeInit();
/**
* Disable systick timer and reset it to default values
*/
SysTick->CTRL = 0;
SysTick->LOAD = 0;
SysTick->VAL = 0;
//reset all periphals
HAL_DeInit();
__disable_irq();
/**
* Remap system memory to address 0x0000 0000 in address space
*/
__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();
/**
* Set jump memory location for system memory
* Use address with 4 bytes offset which specifies jump location where program starts
*/
SysMemBootJump = (void (*)(void)) (*((uint32_t *)(addr + 4)));
/**
* Set main stack pointer.
* This step must be done last otherwise local variables in this function
* don't have proper value since stack pointer is located on different position
*
* Set direct address location which specifies stack pointer in SRAM location
*/
__set_MSP(*(uint32_t *)addr);
/**
* Actually call our function to jump to set location
* This will start system memory execution
*/
SysMemBootJump();
while(1);
}