Skip to content

Commit

Permalink
Jump to system memory boot from user application
Browse files Browse the repository at this point in the history
Fixes stm32duino#706

Signed-off-by: Frederic Pillon <[email protected]>
  • Loading branch information
fpistm committed Sep 17, 2020
1 parent 83dbc1c commit 3e23252
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 2 deletions.
9 changes: 9 additions & 0 deletions cores/arduino/stm32/backup.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@ extern "C" {
#endif /* HID_MAGIC_NUMBER_BKP_VALUE */
#endif /* BL_HID */

#if !defined(SYSBL_MAGIC_NUMBER_BKP_INDEX) && defined(ENABLE_BACKUP_SUPPORT)
#define SYSBL_MAGIC_NUMBER_BKP_INDEX LL_RTC_BKP_DR2
#else
#define SYSBL_MAGIC_NUMBER_BKP_INDEX 0
#endif /* SYSBL_MAGIC_NUMBER_BKP_INDEX */
#ifndef SYSBL_MAGIC_NUMBER_BKP_VALUE
#define SYSBL_MAGIC_NUMBER_BKP_VALUE 0x515B
#endif /* SYSBL_MAGIC_NUMBER_BKP_VALUE */

/* Exported functions ------------------------------------------------------- */
static inline void resetBackupDomain(void)
{
Expand Down
6 changes: 6 additions & 0 deletions cores/arduino/stm32/bootloader.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
extern "C" {
#endif /* __cplusplus */

/* Request to jump to system memory boot */
void jumpToBootloaderRequested(void);

/* Jump to system memory boot from user application */
void jumpToBootloader(void);

#ifdef DTR_TOGGLING_SEQ
/* DTR toggling sequence management */
void dtr_togglingHook(uint8_t *buf, uint32_t *len);
Expand Down
3 changes: 3 additions & 0 deletions cores/arduino/stm32/usb/cdc/usbd_cdc_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@ static int8_t USBD_CDC_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length)
linecoding.format = pbuf[4];
linecoding.paritytype = pbuf[5];
linecoding.datatype = pbuf[6];
if (linecoding.bitrate == 1200) {
jumpToBootloaderRequested();
}
break;

case CDC_GET_LINE_CODING:
Expand Down
143 changes: 143 additions & 0 deletions libraries/SrcWrapper/src/stm32/bootloader.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,147 @@

#include "stm32_def.h"
#include "backup.h"
#include "stm32yyxx_ll_system.h"
#include "usbd_if.h"

/*
* STM32 built-in bootloader in system memory support
*/
/* Private definitions to manage system memory address */
#define SYSMEM_ADDR_COMMON 0xFFF

typedef struct {
uint32_t devID;
uint32_t sysMemAddr;
} devSysMemAddr_str;

devSysMemAddr_str devSysMemAddr[] = {
#ifdef STM32F0xx
{0x440, 0x1FFFEC00},
{0x444, 0x1FFFEC00},
{0x442, 0x1FFFD800},
{0x445, 0x1FFFC400},
{0x448, 0x1FFFC800},
#elif STM32F1xx
{0x412, 0x1FFFF000},
{0x410, 0x1FFFF000},
{0x414, 0x1FFFF000},
{0x420, 0x1FFFF000},
{0x428, 0x1FFFF000},
{0x418, 0x1FFFB000},
{0x430, 0x1FFFE000},
#elif STM32F2xx
{0x411, 0x1FFF0000},
#elif STM32F3xx
{SYSMEM_ADDR_COMMON, 0x1FFFD800},
#elif STM32F4xx
{SYSMEM_ADDR_COMMON, 0x1FFF0000},
#elif STM32F7xx
{SYSMEM_ADDR_COMMON, 0x1FF00000},
#elif STM32G0xx
{SYSMEM_ADDR_COMMON, 0x1FFF0000},
#elif STM32G4xx
{SYSMEM_ADDR_COMMON, 0x1FFF0000},
#elif STM32H7xx
{0x450, 0x1FF00000},
#elif STM32L0xx
{SYSMEM_ADDR_COMMON, 0x1FF00000},
#elif STM32L1xx
{SYSMEM_ADDR_COMMON, 0x1FF00000},
#elif STM32L4xx
{SYSMEM_ADDR_COMMON, 0x1FFF0000},
#elif STM32WBxx
{SYSMEM_ADDR_COMMON, 0x1FFF0000},
#else
#warning "No system memory address for this serie!"
#endif
{0x0000, 0x00000000}
};

uint32_t getSysMemAddr(void)
{
uint32_t sysMemAddr = 0;
if (devSysMemAddr[0].devID == SYSMEM_ADDR_COMMON) {
sysMemAddr = devSysMemAddr[0].sysMemAddr;
} else {
uint32_t devId = LL_DBGMCU_GetDeviceID();
for (uint32_t id = 0; devSysMemAddr[id].devID != 0; id++) {
if (devSysMemAddr[id].devID == devId) {
sysMemAddr = devSysMemAddr[id].sysMemAddr;
break;
}
}
}
return sysMemAddr;
}

/* Request to jump to system memory boot */
WEAK void jumpToBootloaderRequested(void)
{
enableBackupDomain();
setBackupRegister(SYSBL_MAGIC_NUMBER_BKP_INDEX, SYSBL_MAGIC_NUMBER_BKP_VALUE);
NVIC_SystemReset();
}

/* Jump to system memory boot from user application */
WEAK void jumpToBootloader(void)
{
enableBackupDomain();
if (getBackupRegister(SYSBL_MAGIC_NUMBER_BKP_INDEX) == SYSBL_MAGIC_NUMBER_BKP_VALUE) {
setBackupRegister(SYSBL_MAGIC_NUMBER_BKP_INDEX, 0);

#ifdef USBCON
USBD_reenumerate();
#endif
void (*sysMemBootJump)(void);

/**
* Get system memory address
*
* Available in AN2606 document:
* Table xxx Bootloader device-dependent parameters
*/
volatile uint32_t sysMem_addr = getSysMemAddr();
/*
* If the system address is not not referenced in 'devSysMemAddr' array,
* does not do anything
*/
if (sysMem_addr != 0) {
#ifdef __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH
/* Remap system Flash memory at address 0x00000000 */
__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();
#endif

/**
* 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 *)(sysMem_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 *)sysMem_addr);

/**
* Jump to set location
* This will start system memory execution
*/
sysMemBootJump();

while (1);
}
}
}

/*
* Legacy maple bootloader support
*/
#ifdef BL_LEGACY_LEAF
void dtr_togglingHook(uint8_t *buf, uint32_t *len)
{
Expand All @@ -17,6 +157,9 @@ void dtr_togglingHook(uint8_t *buf, uint32_t *len)
}
#endif /* BL_LEGACY_LEAF */

/*
* HID bootloader support
*/
#ifdef BL_HID
void dtr_togglingHook(uint8_t *buf, uint32_t *len)
{
Expand Down
8 changes: 6 additions & 2 deletions libraries/SrcWrapper/src/stm32/hw_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@
*
******************************************************************************
*/
#include "stm32_def.h"
#include "bootloader.h"
#include "dwt.h"
#include "hw_config.h"
#include "usbd_if.h"
#include "dwt.h"
#include "stm32_def.h"

#ifdef __cplusplus
extern "C" {
Expand All @@ -59,6 +60,9 @@ void hw_config_init(void)
/* Initialize the HAL */
HAL_Init();

/* Check if a jump to system memory boot requested */
jumpToBootloader();

/* Configure the system clock */
SystemClock_Config();

Expand Down

0 comments on commit 3e23252

Please sign in to comment.