I am attempting to reset into the boot loader via the REPL via:
import microcontroller
microcontroller.on_next_reset(microcontroller.RunMode.BOOTLOADER)
microcontroller.reset()
I am able to get to the boot loader on 3.0.0 via double clicking the reset button, but would love for the REPL method to also be supported as I'm developing a custom CircuitPython board that does not have a reset button.
Hi @osterwood! I'm excited to hear you are designing a custom board! I'd love to have it supported in this repo when you are ready.
@jepler was just asking me about this bug too. I glanced at the related code but didn't see anything super obvious. Its a matter of writing a special value to a particular memory location before resetting. So, its likely a change in the linker scripts (which defines the location) that broke it.
I don't have cycles to currently look at it (I'm heads down on audioio and audiobusio). We'll definitely fix it up before a stable release and my guess is @jepler will fix it in the next few days if you don't beat him to it. :-)
We're both on our Discord if you want to sync up over chat.
Thanks!
Thanks for the quick reply! I'm not the right person to do a deep dive into linker scripts, so I'll watch and learn from the sidelines on this one.
I will be submitting patches once the next board rev is in and pin definitions are finalized. Thanks so much.
By the way -- really enjoyed your interview on The Amp Hour.
Yes, something has moved _estack by 4 bytes! Pursuing further...
In CircuitPython 2.x branch, build-trinket_m0/firmware.elf.map:
Name Origin Length Attributes
FLASH 0x0000000000002000 0x000000000002e000 xr
RAM 0x0000000020000000 0x0000000000008000 xrw
*default* 0x0000000000000000 0xffffffffffffffff
Linker script and memory map
0x0000000020007ffc _estack = ((ORIGIN (RAM) + LENGTH (RAM)) - 0x4)
0x0000000020007ffc _bootloader_dbl_tap = _estack
In master branch, build-trinket_m0/firmware.elf.map:
Name Origin Length Attributes
FLASH 0x0000000000002000 0x000000000002e000 xr
RAM 0x0000000020000000 0x0000000000008000 xrw
*default* 0x0000000000000000 0xffffffffffffffff
Linker script and memory map
0x0000000020007ff8 _estack = ((ORIGIN (RAM) + LENGTH (RAM)) - 0x8)
0x0000000020007ff8 _bootloader_dbl_tap = _estack
The culprit commit is efbf08266b6d17a383c498140c1498e0161139ce to ensure the stack is 8-byte aligned. However, without updating the bootloader, _bootloader_dbl_tap must remain at the same memory location, not move down 4 bytes with _estack.
Here are the definitions used at the tip of adafruit/uf2-samd21@c91ce29a4826f3e247a31bd193c0b2c8b6be9eea
#ifdef SAMD21
#define DBL_TAP_PTR ((volatile uint32_t *)(HMCRAMC0_ADDR + HMCRAMC0_SIZE - 4))
#endif
#ifdef SAMD51
#define DBL_TAP_PTR ((volatile uint32_t *)(HSRAM_ADDR + HSRAM_SIZE - 4))
#endif
so it looks like the _bootloader_dbl_tap address should be corrected on sam d21 and d51. However, I only have a trinket m0 to test with. Pull request coming up, assuming this analysis is all accurate.