From 2f78bb956695e778fa596408a10593660312a7de Mon Sep 17 00:00:00 2001 From: Ian Rees Date: Fri, 30 Jul 2021 11:13:47 +1200 Subject: [PATCH 1/2] Make the magic "enter bootloader" address constant To enter the bootloader, app sets *0x20000000=0xf02669ef and reboots --- bootloader.c | 13 ++++++------- linker/samd11d14.ld | 5 +++++ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/bootloader.c b/bootloader.c index 1ba99f2..99ff643 100644 --- a/bootloader.c +++ b/bootloader.c @@ -226,9 +226,8 @@ static void USB_Service(void) } #ifdef USE_DBL_TAP - extern int __RAM_segment_used_end__; - static volatile uint32_t *DBL_TAP_PTR = (volatile uint32_t *)(&__RAM_segment_used_end__); #define DBL_TAP_MAGIC 0xf02669ef + static volatile uint32_t __attribute__((section(".dont_move"))) double_tap; #endif void bootloader(void) @@ -259,20 +258,20 @@ void bootloader(void) return; /* we've checked everything and there is no reason to run the bootloader */ #else if (PM->RCAUSE.reg & PM_RCAUSE_POR) - *DBL_TAP_PTR = 0; /* a power up event should never be considered a 'double tap' */ + double_tap = 0; /* a power up event should never be considered a 'double tap' */ - if (*DBL_TAP_PTR == DBL_TAP_MAGIC) + if (double_tap == DBL_TAP_MAGIC) { /* a 'double tap' has happened, so run bootloader */ - *DBL_TAP_PTR = 0; + double_tap = 0; goto run_bootloader; } /* postpone boot for a short period of time; if a second reset happens during this window, the "magic" value will remain */ - *DBL_TAP_PTR = DBL_TAP_MAGIC; + double_tap = DBL_TAP_MAGIC; volatile int wait = 65536; while (wait--); /* however, if execution reaches this point, the window of opportunity has closed and the "magic" disappears */ - *DBL_TAP_PTR = 0; + double_tap = 0; return; #endif diff --git a/linker/samd11d14.ld b/linker/samd11d14.ld index 00dc3cc..9ef2cf6 100644 --- a/linker/samd11d14.ld +++ b/linker/samd11d14.ld @@ -67,6 +67,11 @@ SECTIONS KEEP(*(.bss.$RESERVED*)) } > ram + .dont_move_block (NOLOAD): ALIGN(4) + { + *(.dont_move) + } + .data : ALIGN(4) { FILL(0xff) From 02661fcce27c9a7f6cf34dce44277f3c2f24c47d Mon Sep 17 00:00:00 2001 From: Peter Lawrence Date: Fri, 30 Jul 2021 09:51:55 -0500 Subject: [PATCH 2/2] make Crossworks compatible; increment bcdDevice in USB descriptor to make change evident --- README.md | 10 +++++----- bootloader.c | 2 +- linker/samd11d14.ld | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 1526424..80f6304 100644 --- a/README.md +++ b/README.md @@ -48,12 +48,12 @@ The USBCRM mode should be universal, as it doesn't depend on optional external c Pre-compiled images are already available via this project's Releases tab. -[Rowley Crossworks for ARM](http://www.rowley.co.uk/arm/) is presently suggested to compile this code, as it includes support for Clang; at this time, I am not aware of any other ready-to-use (and multi-OS to boot) Clang ARM cross-compiler package that I can readily point users to. With Crossworks for ARM v4.6.1, compiling v1.05 using the Clang 9.0.1 compiler produces a 1003 byte image. The more mainstream GCC lags behind Clang, although more recent GCC versions produce code that is less overweight than in years past. +[Rowley Crossworks for ARM](http://www.rowley.co.uk/arm/) is presently suggested to compile this code, as it includes support for Clang; at this time, I am not aware of any other ready-to-use (and multi-OS to boot) Clang ARM cross-compiler package that I can readily point users to. With Crossworks for ARM v4.8.1, compiling v1.06 using the Clang 11.1.0 compiler produces a 995 byte image. The more mainstream GCC lags behind Clang, although more recent GCC versions produce code that is less overweight than in years past. -|bootloader variant|Clang 9.0.1 (-O1) |GNU Arm 2018-q3 (-Os) |GNU Arm 2019-q4 (-Os) | -|------------------|------------------|----------------------|----------------------| -| USE_DBL_TAP | 1003 bytes | 1044 bytes (too big!)| 1041 bytes (too big!)| -| GPIO input | 979 bytes | 1008 bytes | 1006 bytes | +|bootloader variant|Clang 9.0.1 (-O1) |Clang 11.1.0 (-O1) |GNU Arm 2018-q3 (-Os) |GNU Arm 2019-q4 (-Os) | +|------------------|------------------|-------------------|----------------------|----------------------| +| USE_DBL_TAP | 1003 bytes | 995 bytes | 1044 bytes (too big!)| 1041 bytes (too big!)| +| GPIO input | 979 bytes | 975 bytes | 1008 bytes | 1006 bytes | A Makefile supporting GCC is provided, but even if you have the latest GCC, it may not be able to output a version within the 1024 bytes available. The latest GCC for ARM can be here: [GNU Arm Embedded Toolchain](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm). Note that if you are adapting the Makefile for use with clang, try replacing the "-Os" argument in CFLAGS with something like "-O1" if the output size is larger than expected. diff --git a/bootloader.c b/bootloader.c index 99ff643..a33df9b 100644 --- a/bootloader.c +++ b/bootloader.c @@ -227,7 +227,7 @@ static void USB_Service(void) #ifdef USE_DBL_TAP #define DBL_TAP_MAGIC 0xf02669ef - static volatile uint32_t __attribute__((section(".dont_move"))) double_tap; + static volatile uint32_t __attribute__((section(".vectors_ram"))) double_tap; #endif void bootloader(void) diff --git a/linker/samd11d14.ld b/linker/samd11d14.ld index 9ef2cf6..35e9ced 100644 --- a/linker/samd11d14.ld +++ b/linker/samd11d14.ld @@ -69,7 +69,7 @@ SECTIONS .dont_move_block (NOLOAD): ALIGN(4) { - *(.dont_move) + *(.vectors_ram) } .data : ALIGN(4)