Circuitpython: Reset into boot loader from REPL [CP3.0-alpha-3]

Created on 3 Apr 2018  路  4Comments  路  Source: adafruit/circuitpython

I am attempting to reset into the boot loader via the REPL via:

import microcontroller
microcontroller.on_next_reset(microcontroller.RunMode.BOOTLOADER)
microcontroller.reset()
  • When running 2.2.1 : the board properly resets into BOOTLOADER mode (with the uf2 file visible in the mounted disk).
  • When running 2.2.4 : correct behavior (same as 2.2.1).
  • When running 3.0.0-alpha.3 : the board resets into normal running mode. Bootloader mode seems to be skipped or ignored.

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.

atmel-samd bug

All 4 comments

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ladyada picture ladyada  路  5Comments

kbanks-krobotics picture kbanks-krobotics  路  5Comments

wallarug picture wallarug  路  6Comments

timonsku picture timonsku  路  4Comments

kevinjwalters picture kevinjwalters  路  7Comments