arduino / arduino/Arduino

Caterina bootKey position is in the middle of RAM on Leonardo

Open
#10,377 0 comments 0 reactions 0 assignees View on GitHub
Architecture: AVR Component: Bootloader Type: Bug
Dominant language
Java
Stars
14.6k
Forks
7k
PR merge metrics
No merged PRs in 30d

Description

This has been discussed at length in #2474 and the core was fixed to allow bootKey to live at RAMEND-1 rather than the hardcoded 0x800, which is in the middle of RAM on Leonardo/32u4 boards and boards with more than 2kB of RAM that use this code. The changes made in that bug report are rather pointless without an updated bootloader and board definitions, as mentioned there as well but nothing has happened since 2016 (unless I'm mistaken, but the current Caterina.c hasn't been touched in 8 years according to Git)

Case in point: I have a pretty large sketch that has a 1kB display buffer that's updated at about 20fps, well within the 120ms watchdog timeout for the reset. Adding more features has pushed the display buffer to 0x437-0x837, so when the reset is triggered, the bootKey is overwritten before the watchdog fires, and the chip resets but starts the sketch rather than going into the bootloader. I went to some lengths to keep my code "small" (27868/28672 at the moment) while I could have done away with the USB bit altogether (saving me some kBs), but I liked the practical side of it so I kept it and then got a bit disappointed to run into this issue.

I could hack up several different fixes but I think I don't know nearly enough about which other boards use this code and the reasons behind this magic position to write something good for everyone. ~~One possible fix without having to re-flash the bootloader would be to write the bootKey at RAMEND-1 and have the sketch check for it in main() (so before setup()), write it to 0x800 and restart. That's a pretty ugly hack though and costs a few bytes of sketch flash.~~ The bootloader overwrites it so that doesn't work.

The "best" fix is flashing the bootloader. I think this should be possible "in place", I don't see any reason why not because it's "just somewhere in flash". Maybe this can be done through a (modified) Caterina as a sketch (so it's not writing where it's executing) with the very slight risk of bricking the device (power outage etc). Is that reasoning a bit sound? That would save the hassle of having to hook up all your boards to a programmer, and it would be nice if this were exposed as an option in the IDE or arduino-cli. That would make it easier for beginners and people without separate programmers. I could try hacking this up if I have some spare time.

Contributor guide

Open the contributing guide

Research direction

Start with the discussion in issue #2474 and the current Caterina.c, then inspect the relevant bootloader and board definitions for Leonardo/32u4 and larger-RAM boards. Determine the agreed bootKey placement and whether an in-place flashing path is viable; done requires an updated bootloader and board definitions that prevent the reset key from being overwritten.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
embedded-iot
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.