In my testing the USB stack compiled by default because we’re using a Leonardo takes 3kb of Flash. The only purpose this stack exists is to allow the IDE (or other tools) to “blink” the device by changing the baud rate of the USB serial port - thereby throwing it into bootloader mode. The one other use is for USB serial support… but I don’t think that is a requirement for most stand-alone games.
If we added this support (go direct to bootloader) into the main library (Arduboy2) we could add a “software” reset button. The sequence for reprogramming would be to hold down X, power on - you’d then have the 8 second bootloader window to hit “upload” . This would disable the ability for the IDE to reboot the device.
The upside is that you get back 3kb of Flash RAM that could be used for more complex sketches.
Thoughts?
How to do it (provide your own main() in your sketch):
// this main is extracted from the Arduino sources, simply removing the
// USB init and serial port event handling (since you can't have serial on
// Arduboy without USB anyways)
int main()
{
init();
setup();
for (;;) {
loop();
}
return 0;
}
BEWARE of trying this on a dev kit since they are much harder to hardware reset since they have no reset pin.
To be clear this is already a decision each program author can make on their own - without support from the library. Someone using such a sketch would then (without library support) simply have to use the reset pin on the Arduboy itself to allow reprogramming (vs holding down a button during boot).
If this can be built into a sketch itself, without library support, why can’t “holding down a button during boot” be built into the sketch as well?
A word of caution on using the reset button: When you press this button you’re putting a shear force on the solder joints that secure the button to the circuit board. There are no pins or other mechanical devices holding the reset button in place, just the surface mount solder joints.
If using the reset button becomes a requirement, there’s a risk of people breaking the button off by using excessive force when pressing it. There have already been instances of this happening.
If using the reset button becomes a requirement, there’s a risk of people breaking the button off by using excessive force when pressing it. There have already been instances of this happening.
Sounds a little scary, but for 3kb extra flash it could be totally worth it. Maybe it could be a button press during the Arduboy dropdown graphic. Maybe once the logo falls all the way and pauses it could say in the corner “Hold A to enter reflash” or something. It wouldn’t take much space compared to what is saved and would make it a little more clear to casual users. Is that possible? Or does it have to be done at reboot?
Why wait for the logo? Sense the button right after power up, like “flashlight” (UP button) and “system control” (B button) do now. The latest Arduboy 2 library already looks for the RIGHT button while the logo is scrolling, to skip the logo.
To encourage uniformity - the same reason we added all the other “system” stuff to the library. This one is a bit weird though which is why I brought it up for discussion. 3kb is nothing to sneeze at though.
Not sure there would be an API… we’d just decide on a key-combo and if you held that down it would jump to the bootloader… so I think the real discussion is the merits of this and if making it a little hard to re-flash (loosing the USB triggered reboot) is worth the effort to get an additional 3kb.
Of course you could get a little fancier with showing some text on the screen - and if this becomes a popular approach I think that would be quite nice… I think you could get it so the text would stay onscreen after the bootloader took control.
I don’t have a concrete suggestion yet, wanted to see how people responded to the idea.
So to actually recover the 3K, a sketch would provide it’s own main()?
I thought maybe you would want to make it easier, like adding a library function called minimalMain(), so the sketch would just do:
int main() {
Arduboy2::minimalMain();
}
minimalMain() would be a static function so it could be called as above, without needing to create the Arduboy2 object beforehand. The minimalMain() function could also include the test for the “enter bootloader” button at its start.
Since the goal of this is to save memory, I wouldn’t add all the code to display text. Just use the RGB LED, as is currently done with the “system control” function. We could light it magenta (which works even with the units with the RGB LED reversed) to indicate “bootloader initiated”.
OH. I don’t love the name, but that’s a great idea. So you just include that boilerplate and do everything else normally… the only thing that bugs me about this is that now the bootloader check is happening even before .start() which wouldn’t happen until setup() was called… one benefit though is that this would easily prevent the bootloader button from even getting compiled in if you weren’t using the smaller main.
I really wanted to show a little something on the screen considering we’re getting 3kb back. We made room for 190 bytes for a logo seems we could make a few bytes room for some 8 pixel high text pushed directly out over SPI (making no assumption about what type of display mode you might decide to use later).
I’m not sure the LED can stay lit after you transfer control to the bootloader. You’d need some testing. If so that’s OK I guess.
Another alternative is showing the existing bootlogo but inverting the screen. One psychological thing here is that people get stressed when they think they might have bricked their device. Being able to immediately trigger bootloader mode via software AND even see the screen light up and show a graphic would reassure “all is well” better than an LED - at least in my mind.
No, you never seem to like my function names, and of course the name is negotiable. I just quickly chose something that describes what it does.
The existing boot logo is optional. Some sketches use boot() to save memory by eliminating the boot logo code. I think lighting the LED is sufficient.
However, if you want to put something on the screen, we could have a second function. You would use minimalMain() for just the LED or minimalMainWithScreenText() for the extra on screen indication. (Yes, we would come up with a better name )
Possibly not. The bootloader might set all the pins to inputs (I haven’t looked into this). We could still light the LED and then call delay() for a second or so before jumping to the bootloader, for visual feedback.
No one has answered the big question though of if the 3kb of space is worth a slightly different reflashing procedure and whether that would confuse any of our users or not.
I always use flashlight mode to flash something on the Arduboy. If there was a way to force the use of that in order to save space, I wouldn’t be opposed to it.
I’ll risk getting chastised for commenting, but I think it would confuse a good portion of the average users. Sure, most all the devs and advanced users will get it right away, but from looking over the other threads involving flashlight mode (or even bootloaders), most don’t get it. I’m guessing if a developer really wanted that extra 3kb, they’d need to crystal clear up front how the end user would load a new game later on. Sounds like the VCP would not be there the next time you plugged the Arduboy in and tried to upload a sketch via the IDE.
Well it’s certain to cause many “I loaded this game and now I can’t load any new ones” posts to the forum, just as sketches that clobber the magic bootloader number in RAM do now. This could be alleviated somewhat by making sure that it’s documented in “big red letters” with the documentation for every game that requires it. We could also add instructions in the troubleshooting section of the Quick Start Guide and the “I’m having problem uploading, can you help?” FAQ on the web site.
The good thing is that using the button all the time wouldn’t hurt anything, so it might get to the point that people always do it, just as @crait has said he does with flashlight mode.
As to whether there would be times that gaining 3K would outweigh the disadvantages, I really can’t say.
@MLXXXp I was meaning to wait mostly for text or graphics somehow instructing the user at that point without necessarily taking much away from the logo. The button press could happen sooner. I would just want it to be painfully obvious to anyone how to re-flash with this system in place. If it’s like flashlight mode, we’d get non-stop posts asking how to flash again after one of these sketches has been loaded up.
If the instructions on how to do it could be completely clear (or at least mostly so) without needing to look anything up I think this could be a really great way to free space and there wouldn’t be any reason to do things the old way.