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
|
||||
* 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 first 4 bytes of the RAM is reserved for the DFU magic word (DFU! to start DFU bootloader)
|
||||
*/
|
||||
|
||||
/* Define memory regions. */
|
||||
MEMORY
|
||||
{
|
||||
rom (rx) : ORIGIN = 0x08000000 + 8K, LENGTH = 128K-8K
|
||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
|
||||
rom (rx) : ORIGIN = 0x08000000 + 8K, LENGTH = 64K - 8K
|
||||
ram (rwx) : ORIGIN = 0x20000000 + 4, LENGTH = 20K - 4
|
||||
}
|
||||
PROVIDE(__application_beginning = ORIGIN(rom));
|
||||
/* 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(__flash_end = ORIGIN(rom) + LENGTH(rom));
|
||||
|
||||
PROVIDE(__dfu_magic = ORIGIN(ram) - 4);
|
||||
|
||||
/* include rest of the definitions for the STM32F1 family */
|
||||
INCLUDE libopencm3_stm32f1.ld
|
||||
|
|
|
@ -36,9 +36,14 @@ void main(void)
|
|||
{
|
||||
// check of DFU mode is forced
|
||||
bool dfu_force = false; // to remember if DFU mode is forced
|
||||
// check if a soft boot has been used
|
||||
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
|
||||
// check if DFU magic DFU! has been written to RAM (e.g. by application to indicate we want to start the DFU bootloader)
|
||||
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;
|
||||
// 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
|
||||
// disable SWJ pin to use as GPIO
|
||||
#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
|
||||
* 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 first 4 bytes of the RAM is reserved for the DFU magic word (DFU! to start DFU bootloader)
|
||||
*/
|
||||
|
||||
/* Define memory regions. */
|
||||
MEMORY
|
||||
{
|
||||
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));
|
||||
/* 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(__flash_end = __application_beginning + 128K - 8K);
|
||||
|
||||
PROVIDE(__dfu_magic = ORIGIN(ram) - 4);
|
||||
|
||||
/* include rest of the definitions for the STM32F1 family */
|
||||
INCLUDE libopencm3_stm32f1.ld
|
||||
|
|
5
global.h
5
global.h
|
@ -701,6 +701,11 @@ extern char __application_end;
|
|||
extern char __flash_end;
|
||||
/** flag set when board user button has been pressed/released */
|
||||
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 */
|
||||
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)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)
|
||||
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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue