bootloader: use magic value in RAM instead of peripheral
This commit is contained in:
parent
20ad271b6a
commit
1ea8b44b2b
|
@ -1,13 +1,14 @@
|
||||||
/* linker script for application running on STM32F103x8 micro-controller
|
/* linker script for application running on STM32F103x8 micro-controller
|
||||||
* the STM32F103xB has 128 KB of flash starting at 0x0800 0000, and 20 KB of RAM starting at 0x2000 0000
|
* the STM32F103xB has 128 KB of flash starting at 0x0800 0000, and 20 KB of RAM starting at 0x2000 0000
|
||||||
* the USB DFU bootloader will take the first 8 KB of flash, followed by the application
|
* the USB DFU bootloader will take the first 8 KB of flash, followed by the application
|
||||||
|
* the first 4 bytes of the RAM is reserved for the DFU magic word (DFU! to start DFU bootloader)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Define memory regions. */
|
/* Define memory regions. */
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
rom (rx) : ORIGIN = 0x08000000 + 8K, LENGTH = 128K-8K
|
rom (rx) : ORIGIN = 0x08000000 + 8K, LENGTH = 64K - 8K
|
||||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
|
ram (rwx) : ORIGIN = 0x20000000 + 4, LENGTH = 20K - 4
|
||||||
}
|
}
|
||||||
PROVIDE(__application_beginning = ORIGIN(rom));
|
PROVIDE(__application_beginning = ORIGIN(rom));
|
||||||
/* only provide application_end and/or flash_end if you want to force a flash size
|
/* only provide application_end and/or flash_end if you want to force a flash size
|
||||||
|
@ -21,5 +22,7 @@ PROVIDE(__flash_end = 0);
|
||||||
PROVIDE(__application_end = ORIGIN(rom) + LENGTH(rom));
|
PROVIDE(__application_end = ORIGIN(rom) + LENGTH(rom));
|
||||||
PROVIDE(__flash_end = ORIGIN(rom) + LENGTH(rom));
|
PROVIDE(__flash_end = ORIGIN(rom) + LENGTH(rom));
|
||||||
|
|
||||||
|
PROVIDE(__dfu_magic = ORIGIN(ram) - 4);
|
||||||
|
|
||||||
/* include rest of the definitions for the STM32F1 family */
|
/* include rest of the definitions for the STM32F1 family */
|
||||||
INCLUDE libopencm3_stm32f1.ld
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
|
@ -36,9 +36,14 @@ void main(void)
|
||||||
{
|
{
|
||||||
// check of DFU mode is forced
|
// check of DFU mode is forced
|
||||||
bool dfu_force = false; // to remember if DFU mode is forced
|
bool dfu_force = false; // to remember if DFU mode is forced
|
||||||
// check if a soft boot has been used
|
// check if DFU magic DFU! has been written to RAM (e.g. by application to indicate we want to start the DFU bootloader)
|
||||||
if (0 == (RCC_CSR & 0xfc000000)) { // no reset flag present -> this was a soft reset using scb_reset_core() after clearing the flags using RCC_CSR_RMVF, very probably to start the DFU mode
|
if ('D' == __dfu_magic[0] && 'F' == __dfu_magic[1] && 'U' == __dfu_magic[2] && '!' == __dfu_magic[3]) { // verify if the DFU magic is set
|
||||||
dfu_force = true;
|
dfu_force = true;
|
||||||
|
// clear DFU magic
|
||||||
|
__dfu_magic[0] = 0;
|
||||||
|
__dfu_magic[1] = 0;
|
||||||
|
__dfu_magic[2] = 0;
|
||||||
|
__dfu_magic[3] = 0;
|
||||||
} else { // check if the force DFU mode input is set
|
} else { // check if the force DFU mode input is set
|
||||||
// disable SWJ pin to use as GPIO
|
// disable SWJ pin to use as GPIO
|
||||||
#if (GPIO(B) == GPIO(DFU_FORCE_PORT)) && (GPIO(4) == GPIO(DFU_FORCE_PIN))
|
#if (GPIO(B) == GPIO(DFU_FORCE_PORT)) && (GPIO(4) == GPIO(DFU_FORCE_PIN))
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
/* linker script for application running on STM32F103x8 micro-controller
|
/* linker script for application running on STM32F103x8 micro-controller
|
||||||
* the STM32F103xB has 128 KB of flash starting at 0x0800 0000, and 20 KB of RAM starting at 0x2000 0000
|
* the STM32F103xB has 128 KB of flash starting at 0x0800 0000, and 20 KB of RAM starting at 0x2000 0000
|
||||||
* the USB DFU bootloader will take the first 8 KB of flash, followed by the application
|
* the USB DFU bootloader will take the first 8 KB of flash, followed by the application
|
||||||
|
* the first 4 bytes of the RAM is reserved for the DFU magic word (DFU! to start DFU bootloader)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Define memory regions. */
|
/* Define memory regions. */
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
rom (rx) : ORIGIN = 0x08000000, LENGTH = 8K
|
rom (rx) : ORIGIN = 0x08000000, LENGTH = 8K
|
||||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
|
ram (rwx) : ORIGIN = 0x20000000 + 4, LENGTH = 20K - 4
|
||||||
}
|
}
|
||||||
PROVIDE(__application_beginning = ORIGIN(rom) + LENGTH(rom));
|
PROVIDE(__application_beginning = ORIGIN(rom) + LENGTH(rom));
|
||||||
/* only provide application_end and/or flash_end if you want to force a flash size
|
/* only provide application_end and/or flash_end if you want to force a flash size
|
||||||
|
@ -21,5 +22,7 @@ PROVIDE(__flash_end = 0);
|
||||||
PROVIDE(__application_end = __application_beginning + 128K - 8K);
|
PROVIDE(__application_end = __application_beginning + 128K - 8K);
|
||||||
PROVIDE(__flash_end = __application_beginning + 128K - 8K);
|
PROVIDE(__flash_end = __application_beginning + 128K - 8K);
|
||||||
|
|
||||||
|
PROVIDE(__dfu_magic = ORIGIN(ram) - 4);
|
||||||
|
|
||||||
/* include rest of the definitions for the STM32F1 family */
|
/* include rest of the definitions for the STM32F1 family */
|
||||||
INCLUDE libopencm3_stm32f1.ld
|
INCLUDE libopencm3_stm32f1.ld
|
||||||
|
|
5
global.h
5
global.h
|
@ -701,6 +701,11 @@ extern char __application_end;
|
||||||
extern char __flash_end;
|
extern char __flash_end;
|
||||||
/** flag set when board user button has been pressed/released */
|
/** flag set when board user button has been pressed/released */
|
||||||
extern volatile bool button_flag;
|
extern volatile bool button_flag;
|
||||||
|
/** symbol for the DFU magic word
|
||||||
|
* @note this symbol will be provided by the linker script
|
||||||
|
*/
|
||||||
|
extern char __dfu_magic[4];
|
||||||
|
|
||||||
/** flag set when user input is available */
|
/** flag set when user input is available */
|
||||||
extern volatile bool user_input_available;
|
extern volatile bool user_input_available;
|
||||||
|
|
||||||
|
|
|
@ -280,9 +280,13 @@ static void usb_dfu_detach(usbd_device *usbd_dev, struct usb_setup_data *req)
|
||||||
{
|
{
|
||||||
(void)usbd_dev; // variable not used
|
(void)usbd_dev; // variable not used
|
||||||
(void)req; // variable not used
|
(void)req; // variable not used
|
||||||
RCC_CSR |= RCC_CSR_RMVF; // clear reset flag for the bootloader to detect the core reset
|
|
||||||
usb_disconnect(); // USB detach (disconnect to force re-enumeration)
|
usb_disconnect(); // USB detach (disconnect to force re-enumeration)
|
||||||
scb_reset_core(); // reset device (only the core, to the peripheral stay configured)
|
// set DFU magic
|
||||||
|
__dfu_magic[0] = 'D';
|
||||||
|
__dfu_magic[1] = 'F';
|
||||||
|
__dfu_magic[2] = 'U';
|
||||||
|
__dfu_magic[3] = '!';
|
||||||
|
scb_reset_system(); // reset system (core and peripherals)
|
||||||
while (true); // wait for the reset to happen
|
while (true); // wait for the reset to happen
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue