Skip to content

Commit b417750

Browse files
committed
Jump to system memory boot from user application
Fixes stm32duino#706 Signed-off-by: Frederic Pillon <[email protected]>
1 parent 3d76761 commit b417750

File tree

5 files changed

+164
-2
lines changed

5 files changed

+164
-2
lines changed

cores/arduino/stm32/backup.h

+9
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,15 @@ extern "C" {
5858
#endif /* HID_MAGIC_NUMBER_BKP_VALUE */
5959
#endif /* BL_HID */
6060

61+
#if !defined(SYSBL_MAGIC_NUMBER_BKP_INDEX) && defined(ENABLE_BACKUP_SUPPORT)
62+
#define SYSBL_MAGIC_NUMBER_BKP_INDEX LL_RTC_BKP_DR2
63+
#else
64+
#define SYSBL_MAGIC_NUMBER_BKP_INDEX 0
65+
#endif /* SYSBL_MAGIC_NUMBER_BKP_INDEX */
66+
#ifndef SYSBL_MAGIC_NUMBER_BKP_VALUE
67+
#define SYSBL_MAGIC_NUMBER_BKP_VALUE 0x515B
68+
#endif /* SYSBL_MAGIC_NUMBER_BKP_VALUE */
69+
6170
/* Exported functions ------------------------------------------------------- */
6271
static inline void resetBackupDomain(void)
6372
{

cores/arduino/stm32/bootloader.c

+140
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,144 @@
22

33
#include "stm32_def.h"
44
#include "backup.h"
5+
#include "stm32yyxx_ll_system.h"
6+
#include "usbd_if.h"
57

8+
/*
9+
* STM32 built-in bootloader in system memory support
10+
*/
11+
/* Private definitions to manage system memory address */
12+
#define SYSMEM_ADDR_COMMON 0xFFF
13+
14+
typedef struct {
15+
uint32_t devID;
16+
uint32_t sysMemAddr;
17+
} devSysMemAddr_str;
18+
19+
devSysMemAddr_str devSysMemAddr[] = {
20+
#ifdef STM32F0xx
21+
{0x440, 0x1FFFEC00},
22+
{0x444, 0x1FFFEC00},
23+
{0x442, 0x1FFFD800},
24+
{0x445, 0x1FFFC400},
25+
{0x448, 0x1FFFC800},
26+
{0x442, 0x1FFFD800},
27+
#elif STM32F1xx
28+
{0x412, 0x1FFFF000},
29+
{0x410, 0x1FFFF000},
30+
{0x414, 0x1FFFF000},
31+
{0x420, 0x1FFFF000},
32+
{0x428, 0x1FFFF000},
33+
{0x418, 0x1FFFB000},
34+
{0x430, 0x1FFFE000},
35+
#elif STM32F2xx
36+
{0x411, 0x1FFF0000},
37+
#elif STM32F3xx
38+
{SYSMEM_ADDR_COMMON, 0x1FFFD800},
39+
#elif STM32F4xx
40+
{SYSMEM_ADDR_COMMON, 0x1FFF0000},
41+
#elif STM32F7xx
42+
{SYSMEM_ADDR_COMMON, 0x1FF00000},
43+
#elif STM32G0xx
44+
{SYSMEM_ADDR_COMMON, 0x1FFF0000},
45+
#elif STM32G4xx
46+
{SYSMEM_ADDR_COMMON, 0x1FFF0000},
47+
#elif STM32H7xx
48+
{0x450, 0x1FF00000},
49+
#elif STM32L0xx
50+
{SYSMEM_ADDR_COMMON, 0x1FF00000},
51+
#elif STM32L1xx
52+
{SYSMEM_ADDR_COMMON, 0x1FF00000},
53+
#elif STM32L4xx
54+
{SYSMEM_ADDR_COMMON, 0x1FFF0000},
55+
#elif STM32WBxx
56+
{SYSMEM_ADDR_COMMON, 0x1FFF0000},
57+
#else
58+
#warning "No system memory address for this serie!"
59+
#endif
60+
{0x0000, 0x00000000}
61+
};
62+
63+
uint32_t getSysMemAddr(void)
64+
{
65+
uint32_t sysMemAddr = 0;
66+
if (devSysMemAddr[0].devID == SYSMEM_ADDR_COMMON) {
67+
sysMemAddr = devSysMemAddr[0].sysMemAddr;
68+
} else {
69+
uint32_t devId = LL_DBGMCU_GetDeviceID();
70+
for (uint32_t id = 0; devSysMemAddr[id].devID != 0; id++) {
71+
if (devSysMemAddr[id].devID == devId) {
72+
sysMemAddr = devSysMemAddr[id].sysMemAddr;
73+
break;
74+
}
75+
}
76+
}
77+
return sysMemAddr;
78+
}
79+
80+
/* Request to jump to system memory boot */
81+
WEAK void jumpToBootloaderRequested(void)
82+
{
83+
enableBackupDomain();
84+
setBackupRegister(SYSBL_MAGIC_NUMBER_BKP_INDEX, SYSBL_MAGIC_NUMBER_BKP_VALUE);
85+
NVIC_SystemReset();
86+
}
87+
88+
/* Jump to system memory boot from user application */
89+
WEAK void jumpToBootloader(void)
90+
{
91+
enableBackupDomain();
92+
if (getBackupRegister(SYSBL_MAGIC_NUMBER_BKP_INDEX) == SYSBL_MAGIC_NUMBER_BKP_VALUE) {
93+
setBackupRegister(SYSBL_MAGIC_NUMBER_BKP_INDEX, 0);
94+
95+
#ifdef USBCON
96+
USBD_reenumerate();
97+
#endif
98+
void (*sysMemBootJump)(void);
99+
100+
/**
101+
* Get system memory address
102+
*
103+
* Available in AN2606 document:
104+
* Table xxx Bootloader device-dependent parameters
105+
*/
106+
volatile uint32_t sysMem_addr = getSysMemAddr();
107+
if (sysMem_addr != 0) {
108+
#ifdef __HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH
109+
/* Remap system Flash memory at address 0x00000000 */
110+
__HAL_SYSCFG_REMAPMEMORY_SYSTEMFLASH();
111+
#endif
112+
113+
/**
114+
* Set jump memory location for system memory
115+
* Use address with 4 bytes offset which specifies jump location
116+
* where program starts
117+
*/
118+
sysMemBootJump = (void (*)(void))(*((uint32_t *)(sysMem_addr + 4)));
119+
120+
/**
121+
* Set main stack pointer.
122+
* This step must be done last otherwise local variables in this function
123+
* don't have proper value since stack pointer is located on different position
124+
*
125+
* Set direct address location which specifies stack pointer in SRAM location
126+
*/
127+
__set_MSP(*(uint32_t *)sysMem_addr);
128+
129+
/**
130+
* Jump to set location
131+
* This will start system memory execution
132+
*/
133+
sysMemBootJump();
134+
135+
while (1);
136+
}
137+
}
138+
}
139+
140+
/*
141+
* Legacy maple bootloader support
142+
*/
6143
#ifdef BL_LEGACY_LEAF
7144
void dtr_togglingHook(uint8_t *buf, uint32_t *len)
8145
{
@@ -17,6 +154,9 @@ void dtr_togglingHook(uint8_t *buf, uint32_t *len)
17154
}
18155
#endif /* BL_LEGACY_LEAF */
19156

157+
/*
158+
* HID bootloader support
159+
*/
20160
#ifdef BL_HID
21161
void dtr_togglingHook(uint8_t *buf, uint32_t *len)
22162
{

cores/arduino/stm32/bootloader.h

+6
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@
1414
extern "C" {
1515
#endif /* __cplusplus */
1616

17+
/* Request to jump to system memory boot */
18+
void jumpToBootloaderRequested(void);
19+
20+
/* Jump to system memory boot from user application */
21+
void jumpToBootloader(void);
22+
1723
#ifdef DTR_TOGGLING_SEQ
1824
/* DTR toggling sequence management */
1925
void dtr_togglingHook(uint8_t *buf, uint32_t *len);

cores/arduino/stm32/hw_config.c

+6-2
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,11 @@
3535
*
3636
******************************************************************************
3737
*/
38-
#include "stm32_def.h"
38+
#include "bootloader.h"
39+
#include "dwt.h"
3940
#include "hw_config.h"
4041
#include "usbd_if.h"
41-
#include "dwt.h"
42+
#include "stm32_def.h"
4243

4344
#ifdef __cplusplus
4445
extern "C" {
@@ -59,6 +60,9 @@ void hw_config_init(void)
5960
/* Initialize the HAL */
6061
HAL_Init();
6162

63+
/* Check if a jump to system memory boot requested */
64+
jumpToBootloader();
65+
6266
/* Configure the system clock */
6367
SystemClock_Config();
6468

cores/arduino/stm32/usb/cdc/usbd_cdc_if.c

+3
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,9 @@ static int8_t USBD_CDC_Control(uint8_t cmd, uint8_t *pbuf, uint16_t length)
168168
linecoding.format = pbuf[4];
169169
linecoding.paritytype = pbuf[5];
170170
linecoding.datatype = pbuf[6];
171+
if (linecoding.bitrate == 1200) {
172+
jumpToBootloaderRequested();
173+
}
171174
break;
172175

173176
case CDC_GET_LINE_CODING:

0 commit comments

Comments
 (0)