aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKévin Redon <kredon@sysmocom.de>2019-02-14 18:35:33 +0100
committerKévin Redon <kredon@sysmocom.de>2019-02-14 18:45:20 +0100
commit45554d71f974c5382dd9f5cec104d28a35c5b1b5 (patch)
treeaf2ec55069cc431b3940c9285819334e7e581918
parent93364944911de44fb268da7430bd2da64d4ee794 (diff)
add force DFU using magic value
if the string "DFU!" is found at the beginning of the RAM (e.g. as written by the main application during USB detach), the DFU bootloader will be started. Change-Id: I298e3697c06d352a6e0f47266097844c490e1722
-rw-r--r--README.md8
-rw-r--r--gcc/gcc/same54p20a_flash.ld9
-rw-r--r--usb_dfu_main.c12
3 files changed, 26 insertions, 3 deletions
diff --git a/README.md b/README.md
index 96cf583..dd61824 100644
--- a/README.md
+++ b/README.md
@@ -28,10 +28,16 @@ This implementation support the following USB DFU capabilities:
Set the corresponding attributes in the 'DFUD_IFACE_DESCB' macro definition in the 'usb/class/dfu/device/dfudf_desc.h' file.
+To force the DFU bootloader to start there are several possibilities:
+
+* if the application following the bootloader is invalid (e.g. MSP is not in RAM)
+* if a button is pressed (the button defined in *BUTTON_FORCE_DFU*)
+* if the magic value "DFU!" (e.g. 0x44465521) is set at the start of the RAM (e.g. by the main application when performing a USB detach)
+
Compiling
=========
-Use the 'Makefile' script to compile the source code using the ARM none EABI GCC cross-cimpilig toolchain:
+Use the 'Makefile' script to compile the source code using the ARM none EABI GCC cross-compiling toolchain:
```
cd gcc
make
diff --git a/gcc/gcc/same54p20a_flash.ld b/gcc/gcc/same54p20a_flash.ld
index 08099d2..32ded77 100644
--- a/gcc/gcc/same54p20a_flash.ld
+++ b/gcc/gcc/same54p20a_flash.ld
@@ -36,7 +36,8 @@ SEARCH_DIR(.)
MEMORY
{
rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00100000
- ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000
+ /* The first word of the RAM is used for the DFU magic */
+ ram (rwx) : ORIGIN = 0x20000000 + 4, LENGTH = 0x00040000 - 4
bkupram (rwx) : ORIGIN = 0x47000000, LENGTH = 0x00002000
qspi (rwx) : ORIGIN = 0x04000000, LENGTH = 0x01000000
}
@@ -47,6 +48,12 @@ STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stac
/* Section Definitions */
SECTIONS
{
+ /* Location of the DFU magic. The application must set the magic value "DFU!" (e.g. 0x44465521) at this address to force the DFU bootloader to start (e.g. to perform a DFU detach) */
+ .dfu_magic 0x20000000 :
+ {
+ KEEP(*(.dfu_magic)) ;
+ }
+
.text :
{
. = ALIGN(4);
diff --git a/usb_dfu_main.c b/usb_dfu_main.c
index 96032c5..81b02f8 100644
--- a/usb_dfu_main.c
+++ b/usb_dfu_main.c
@@ -27,6 +27,9 @@
*/
static uint32_t* application_start_address;
+/** Location of the DFU magic value to force starting DFU */
+static uint32_t dfu_magic __attribute__ ((section (".dfu_magic"))) __attribute__ ((__used__));
+
/** Check if the bootloader is valid
* \return true if the bootloader is valid and can be run
* \remark initializes application_start_address
@@ -48,7 +51,14 @@ static bool check_bootloader(void)
*/
static bool check_force_dfu(void)
{
- return (0 == gpio_get_pin_level(BUTTON_FORCE_DFU)); // signal is low when button is pressed
+ if (0x44465521 == dfu_magic) { // check for the magic value which can be set by the main application
+ dfu_magic = 0; // erase value so we don't stay in the DFU bootloader upon reset
+ return true;
+ }
+ if (0 == gpio_get_pin_level(BUTTON_FORCE_DFU)) { // signal is low when button is pressed
+ return true;
+ }
+ return false;
}
/** Check if the application is valid