From bc46b37d71a4894c696cb8987a3bcad2e5feb733 Mon Sep 17 00:00:00 2001 From: Mikkel Jeppesen <2756925+Duckle29@users.noreply.github.com> Date: Mon, 9 Sep 2019 14:40:29 +0200 Subject: [PATCH 1/5] Modify check to allow more software rest to bootloader --- Bootloaders/DFU/BootloaderDFU.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/Bootloaders/DFU/BootloaderDFU.c b/Bootloaders/DFU/BootloaderDFU.c index f20cdd72b..103b0787b 100644 --- a/Bootloaders/DFU/BootloaderDFU.c +++ b/Bootloaders/DFU/BootloaderDFU.c @@ -135,22 +135,19 @@ void Application_Jump_Check(void) /* Check if the device's BOOTRST fuse is set */ if (!(BootloaderAPI_ReadFuse(GET_HIGH_FUSE_BITS) & ~FUSE_BOOTRST)) { - /* If the reset source was not an external reset or the key is correct, clear it and jump to the application */ - if (!(MCUSR & (1 << EXTRF)) || (MagicBootKey == MAGIC_BOOT_KEY)) + /* If the reset source was a power on reset or a brown out reset or the key is correct, clear it and jump to the application */ + if ((MCUSR & (1 << PORF)) || (MCUSR & (1 << BORF)) || (MagicBootKey == MAGIC_BOOT_KEY)) JumpToApplication = true; - /* Clear reset source */ - MCUSR &= ~(1 << EXTRF); + /* Clear reset sources */ + MCUSR &= ~((1 << PORF) & (1 << BORF)); } else { - /* If the reset source was the bootloader and the key is correct, clear it and jump to the application; + /* If the reset source was the bootloader the key is correct. Jump to the application; * this can happen in the HWBE fuse is set, and the HBE pin is low during the watchdog reset */ - if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY)) + if (MagicBootKey == MAGIC_BOOT_KEY) JumpToApplication = true; - - /* Clear reset source */ - MCUSR &= ~(1 << WDRF); } #endif From d3d148de5fb7ab540c56408e9e778c5933cc9499 Mon Sep 17 00:00:00 2001 From: Mikkel Jeppesen <2756925+Duckle29@users.noreply.github.com> Date: Mon, 9 Sep 2019 15:05:54 +0200 Subject: [PATCH 2/5] Switched to some binary logic, and added skip cases to HWBE fuse case --- Bootloaders/DFU/BootloaderDFU.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/Bootloaders/DFU/BootloaderDFU.c b/Bootloaders/DFU/BootloaderDFU.c index 103b0787b..507d04be0 100644 --- a/Bootloaders/DFU/BootloaderDFU.c +++ b/Bootloaders/DFU/BootloaderDFU.c @@ -136,18 +136,22 @@ void Application_Jump_Check(void) if (!(BootloaderAPI_ReadFuse(GET_HIGH_FUSE_BITS) & ~FUSE_BOOTRST)) { /* If the reset source was a power on reset or a brown out reset or the key is correct, clear it and jump to the application */ - if ((MCUSR & (1 << PORF)) || (MCUSR & (1 << BORF)) || (MagicBootKey == MAGIC_BOOT_KEY)) + if ((MCUSR & ((1 << PORF) | (1 << BORF))) || (MagicBootKey == MAGIC_BOOT_KEY)) JumpToApplication = true; /* Clear reset sources */ - MCUSR &= ~((1 << PORF) & (1 << BORF)); + MCUSR &= ~((1 << PORF) | (1 << BORF)); } else { - /* If the reset source was the bootloader the key is correct. Jump to the application; - * this can happen in the HWBE fuse is set, and the HBE pin is low during the watchdog reset */ - if (MagicBootKey == MAGIC_BOOT_KEY) + /* If the reset source was a power on or brown out reset, or reset source was the bootloader (the key would be correct), + * jump to the application; + * this can happen in the HWBE fuse is set, and the HWB pin is low during the watchdog reset */ + if (MagicBootKey == MAGIC_BOOT_KEY || (MCUSR & ((1 << PORF) | (1 << BORF))) JumpToApplication = true; + + /* Clear reset sources */ + MCUSR &= ~((1 << PORF) | (1 << BORF)); } #endif From 5c28c65fab5bf35438a1358d2345f598d781691b Mon Sep 17 00:00:00 2001 From: Mikkel Jeppesen <2756925+Duckle29@users.noreply.github.com> Date: Mon, 9 Sep 2019 15:30:40 +0200 Subject: [PATCH 3/5] Revert HWBE check to just check magic key --- Bootloaders/DFU/BootloaderDFU.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/Bootloaders/DFU/BootloaderDFU.c b/Bootloaders/DFU/BootloaderDFU.c index 507d04be0..d0bfeb1dd 100644 --- a/Bootloaders/DFU/BootloaderDFU.c +++ b/Bootloaders/DFU/BootloaderDFU.c @@ -136,7 +136,7 @@ void Application_Jump_Check(void) if (!(BootloaderAPI_ReadFuse(GET_HIGH_FUSE_BITS) & ~FUSE_BOOTRST)) { /* If the reset source was a power on reset or a brown out reset or the key is correct, clear it and jump to the application */ - if ((MCUSR & ((1 << PORF) | (1 << BORF))) || (MagicBootKey == MAGIC_BOOT_KEY)) + if (MCUSR & ((1 << PORF) | (1 << BORF)) || (MagicBootKey == MAGIC_BOOT_KEY)) JumpToApplication = true; /* Clear reset sources */ @@ -144,14 +144,10 @@ void Application_Jump_Check(void) } else { - /* If the reset source was a power on or brown out reset, or reset source was the bootloader (the key would be correct), - * jump to the application; - * this can happen in the HWBE fuse is set, and the HWB pin is low during the watchdog reset */ - if (MagicBootKey == MAGIC_BOOT_KEY || (MCUSR & ((1 << PORF) | (1 << BORF))) + /* If the reset source was the bootloader the key is correct. Jump to the application; + * this can happen if the HWBE fuse is set, and the HWB pin is low during the watchdog reset */ + if (MagicBootKey == MAGIC_BOOT_KEY) JumpToApplication = true; - - /* Clear reset sources */ - MCUSR &= ~((1 << PORF) | (1 << BORF)); } #endif @@ -161,7 +157,7 @@ void Application_Jump_Check(void) /* If a request has been made to jump to the user application, honor it */ if (JumpToApplication && ApplicationValid) { - /* Turn off the watchdog */ + /* Clear any watchdog reset and turn off the watchdog */ MCUSR &= ~(1 << WDRF); wdt_disable(); From f6234a2e9a03982792b28e859f827a36c2d33e08 Mon Sep 17 00:00:00 2001 From: Mikkel Jeppesen <2756925+Duckle29@users.noreply.github.com> Date: Sun, 27 Oct 2019 22:05:02 +0100 Subject: [PATCH 4/5] Revert changes to work on secondary magic key --- Bootloaders/DFU/BootloaderDFU.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Bootloaders/DFU/BootloaderDFU.c b/Bootloaders/DFU/BootloaderDFU.c index d0bfeb1dd..f20cdd72b 100644 --- a/Bootloaders/DFU/BootloaderDFU.c +++ b/Bootloaders/DFU/BootloaderDFU.c @@ -135,19 +135,22 @@ void Application_Jump_Check(void) /* Check if the device's BOOTRST fuse is set */ if (!(BootloaderAPI_ReadFuse(GET_HIGH_FUSE_BITS) & ~FUSE_BOOTRST)) { - /* If the reset source was a power on reset or a brown out reset or the key is correct, clear it and jump to the application */ - if (MCUSR & ((1 << PORF) | (1 << BORF)) || (MagicBootKey == MAGIC_BOOT_KEY)) + /* If the reset source was not an external reset or the key is correct, clear it and jump to the application */ + if (!(MCUSR & (1 << EXTRF)) || (MagicBootKey == MAGIC_BOOT_KEY)) JumpToApplication = true; - /* Clear reset sources */ - MCUSR &= ~((1 << PORF) | (1 << BORF)); + /* Clear reset source */ + MCUSR &= ~(1 << EXTRF); } else { - /* If the reset source was the bootloader the key is correct. Jump to the application; - * this can happen if the HWBE fuse is set, and the HWB pin is low during the watchdog reset */ - if (MagicBootKey == MAGIC_BOOT_KEY) + /* If the reset source was the bootloader and the key is correct, clear it and jump to the application; + * this can happen in the HWBE fuse is set, and the HBE pin is low during the watchdog reset */ + if ((MCUSR & (1 << WDRF)) && (MagicBootKey == MAGIC_BOOT_KEY)) JumpToApplication = true; + + /* Clear reset source */ + MCUSR &= ~(1 << WDRF); } #endif @@ -157,7 +160,7 @@ void Application_Jump_Check(void) /* If a request has been made to jump to the user application, honor it */ if (JumpToApplication && ApplicationValid) { - /* Clear any watchdog reset and turn off the watchdog */ + /* Turn off the watchdog */ MCUSR &= ~(1 << WDRF); wdt_disable(); From b31d2eb94c4cf4841471447e6c1c25afa1df7c15 Mon Sep 17 00:00:00 2001 From: Mikkel Jeppesen <2756925+Duckle29@users.noreply.github.com> Date: Mon, 28 Oct 2019 02:43:04 +0100 Subject: [PATCH 5/5] Added MagicLoadKey to allow watchdog to bootloader from application --- Bootloaders/DFU/BootloaderDFU.c | 23 ++++++++++++++++++----- Bootloaders/DFU/BootloaderDFU.h | 3 +++ 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/Bootloaders/DFU/BootloaderDFU.c b/Bootloaders/DFU/BootloaderDFU.c index f20cdd72b..03295ccfa 100644 --- a/Bootloaders/DFU/BootloaderDFU.c +++ b/Bootloaders/DFU/BootloaderDFU.c @@ -99,6 +99,11 @@ static uint16_t EndAddr = 0x0000; */ uint16_t MagicBootKey ATTR_NO_INIT; +/** Magic key allowing watchdog reset to bootloader from the application. If BOOTRST is programmed, the application can + * set this to the value \ref MAGIC_LOAD_KEY, which will ensure the bootloader isn't skipped. + */ +uint16_t MagicLoadKey ATTR_NO_INIT; + /** Special startup routine to check if the bootloader was started via a watchdog reset, and if the magic application * start key has been loaded into \ref MagicBootKey. If the bootloader started via the watchdog and the key is valid, @@ -135,12 +140,20 @@ void Application_Jump_Check(void) /* Check if the device's BOOTRST fuse is set */ if (!(BootloaderAPI_ReadFuse(GET_HIGH_FUSE_BITS) & ~FUSE_BOOTRST)) { - /* If the reset source was not an external reset or the key is correct, clear it and jump to the application */ - if (!(MCUSR & (1 << EXTRF)) || (MagicBootKey == MAGIC_BOOT_KEY)) - JumpToApplication = true; + /* If the reset source was not an external reset jump to the application */ + if (!(MCUSR & (1 << EXTRF))) + JumpToApplication = true; + + /* If the reset source was a watchdog reset, and the MagicLoadKey is set, don't jump to the application*/ + if ((MCUSR & (1 << WDRF)) && (MagicLoadKey == MAGIC_LOAD_KEY)) + JumpToApplication = false; + + /* If the boot key is set, force the jump to the application */ + if (MagicBootKey == MAGIC_BOOT_KEY) + JumpToApplication = true; - /* Clear reset source */ - MCUSR &= ~(1 << EXTRF); + /* Clear reset sources */ + MCUSR &= ~((1 << EXTRF) && (1 << WDRF)); } else { diff --git a/Bootloaders/DFU/BootloaderDFU.h b/Bootloaders/DFU/BootloaderDFU.h index bef122c72..d773b4952 100644 --- a/Bootloaders/DFU/BootloaderDFU.h +++ b/Bootloaders/DFU/BootloaderDFU.h @@ -70,6 +70,9 @@ /** Magic bootloader key to unlock forced application start mode. */ #define MAGIC_BOOT_KEY 0xDC42 + /** Magic bootloader key to ensure bootloader isn't skipped. */ + #define MAGIC_LOAD_KEY 0xAC42 + /** Complete bootloader version number expressed as a packed byte, constructed from the * two individual bootloader version macros. */