Idea: Remove the USB stack and regain 3,000 bytes of Flash

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.

1 Like

To encourage uniformity - the same reason we added all the other “system” stuff to the library. :slight_smile: This one is a bit weird though which is why I brought it up for discussion. 3kb is nothing to sneeze at though.

OK. I thought there was a technical reason.

In what way do you envision adding this to the library? What would be the API?

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 :wink:)

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.

My goal was consistency of experience.

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.

1 Like

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. :stuck_out_tongue:

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.

1 Like

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.

I think developers should play with this first and get a feel for how annoying it would (or wouldn’t be). I won’t have much time next week but after that I’ll whip up a quick demo (unless someone wants to beat me to it) of invoking the bootloader from software. Should be as simple as jumping to it (with asm) or more authentically setting the magic memory location and then triggering a watchdog reset.

How many different languages should we support for these instructions? :wink:
So far, the executable code in the library is language agnostic. There’s no hard coded output text anywhere.

On thing to consider is that once the bootloader is invoked you would only have the 8 second window to manually start your compile/upload. Therefore, you would be faced with all the timing problems that you get when using the reset button.

With the “old way” (even if flashlight mode is necessary), you don’t have timing problems because the loader on the PC is able to issue a reset, to invoke the bootloader, at the exact time required.

It’s probably best to look at the USB code we’re removing to see how it invokes the bootloader, and use the same technique.

That might prove a requirement - I’d have to look at the bootloader code again. It might check for the type of boot.

Yeah, that is actually the most annoying thing. There is a way to fix that (and have an unlimited delay) but it would require having the program “destroy itself” by writing 0xFFFF to the beginning of Flash. That permanently enables bootloader mode with no timeout.

What I’m learning is that there is a lot to like about the Arduinos with dedicated USB co-processors.

My thought is that it’s ok to build out this functionality but its use should be deemed “experimental” or “alternative” as mentioned previously, it can create confusion for some users. The main concept is user experience.

It sets a magic number in ram and invokes the AVR command for watchdog reset AFAIK

1 Like