Saving flash question

To save flash as well as RAM I am using Arduboy2Base with my own direct to screen paint functions. In other words, I don’t use any of the print functions the Arduboy library offers. I simply query Arduboy2::font5x7 for the font bitmap and then directly send it to the screen. Do I have to manually delete the print or write functions from the Arduboy2Base library? Or does the compiler do that for me? Just checking if some manual intervention would save more flash memory. Anything else I could remove from Arduboy2Base to free up flash?

I have read the thread eliminating the USB stack to save about 3k of flash. Is anybody actually using this? I may have to resort to it as my last option. Right now I need to free at least 1k of progmem to reach the next step in my development, but ultimately I will need more than that.

Another idea mentioned in this forum I have not yet done is to create my own font5x7 data with only the characters I need. I think I could do with about 40 characters which would save about 1k.

There are no text print or write functions in the ArduboyBase class.

The compiler will only include Arduboy2Base functions that you use (and functions indirectly called by functions that you use).

Yes. Arduventure and some by Press Play On Tape, to name a few.

For suggestions on saving flash memory, including eliminating the USB code, see the Ways to make more code space available to sketches section of the Arduboy2 documentation.

One more possibility, if you’re not using an FX mod Arduboy, don’t mind limiting your audience, and have the programming hardware available to do it, is to install a version of @Mr.Blinky’s Cathy bootloader that frees up an additional 1K or 2K of flash.

If you have the capability to use a ICSP, you could even go to the extreme case of eliminating the bootloader entirely, thus freeing up 4K of flash.

Thanks. If I understand the documentation correctly when including ARDUBOY_NO_USB one has to do the following to upload a new sketch to the Arduboy:

  1. Turn it off
  2. Turn it on while pressing the DOWN button. (starts the bootloader)
  3. Then press the upload button in the Arduino IDE to upload a new sketch.

Why does the docu state “that timing the sequence can sometimes be tricky”. Is the Arduboy after step 2) only for a certain time in the bootloader?

Not necessarily. The sketch can include code to call exitToBootloader(). The recommendation is that exitToBootloader() be called when the user presses DOWN when prompted.

Another way to invoke the bootloader is to press and release the reset button while powered up.

The bootloader only remains in boot mode for about 8 seconds. When uploading from the IDE, the sketch is re-compiled before starting the upload. With a manual reset, often the bootloader exits before the upload starts. I find that timing this can be easier if Show verbose output during: upload is set in the IDE preferences, and you reset to boot mode when you see the port scan messages begin.

Thanks for the timing tip. Don’t understand why it has to be just 8 seconds but it is good enough to explore this possibility for the time being.

Reset can be used for purposes other than uploading a new sketch, such as restarting the existing sketch. I suspect the Arduino bootloader developers used a time that is a trade off between having enough time to upload a new sketch and waiting to restart the existing sketch.

I have read the documentation but am not clear what I would be giving up using these bootloaders.

I think the issue is really that if you max a program to distribute to others, they will most likely be using the ‘default’, larger bootloader and therefore not have enough room to load your program.

1 Like

Here is a crazy thought about saving progmem. I don’t know if the following would even be possible, but here it is. Compressing data stored in progmem is one of the methods that can be used to reduce the size of flash. Would it be possible to compress the program itself, the assembler code? For example, say one would have some kind of execution unit which takes the compressed assembler instructions, decompresses them and then executes them. I don’t know how much one could save that way. How compressible is assembler code? Would a scheme like that even be feasible? Is there a way to write an ‘execute function’ that executes assembler code?

The AVR architecture uses separate address spaces for code and data, so, as far as I know, there’s no way to execute code out of RAM, it has to be read from the flash memory. See https://www.avrfreaks.net/forum/code-execution-ram for a discussion.

1 Like

Just to elaborate on @Mr.Blinky’s reply:

From a general point of view, you’re not giving up anything, at least for the 3K version. The 2K version gives up things that aren’t required just to upload new sketches to an Arduboy, which is all the bootloader is normally used for. As a matter of fact, you gain a few good features (as documented).

The reason the 3K version is smaller than the original Arduino 4K bootloader is that @Mr.Blinky has painstakingly re-implemented and optimised the code in assembly, thus reducing its size but providing all the same capabilities. The 2K version sacrifices some little used and rarely needed functionality.

As I said, and @Mr.Blinky clarified:

The main downside is that if your sketch uses the additional 1K or 2K that’s freed up by using a smaller bootloader, people with “off the shelf” Arduboy’s with the larger bootloader won’t have enough flash space available to upload and use your sketch.

Too bad. The only remaining possibility is to create a custom made byte code and interpreter for it, and then write portions of the application in that byte code. Then this byte code could be compressed/decompressed on the fly. For some applications this may be a way to squeeze more code into the flash, but it would be a huge effort for something that would likely be very application specific.

True, there’s no way to execute code in RAM (nor can you execute from EEPROM). However, it is possible to “self program” flash (which is what the bootloader does to upload a new sketch via USB). In theory, you could have functions that decompress compressed code, write it to an area of flash and then execute it. Part of this functionality would have to reside in a custom bootloader, since code in the application area can’t write to flash.

For instance, you might want to run a regular application at one time, or code to set preferences at another time, but you wouldn’t need both at the same time. The code to do “application” and “set up” could each be compressed. You could uncompress one or the other to a common flash area to execute it.

That said, one drawback to doing this is that flash has a limited number of write cycles, so doing this kind of thing frequently could limit the life of the hardware. And, of course, the other issue is whether the compressed code, along with the required execution area and support code would end up smaller than just having the regular uncompressed code.

Thanks for the additional information. If with the 3k version no functionality is lost, and in fact Arduboy specific functionality is gained, why not make it the default bootloader for the Arduboy? Why not ship the Arduboy loaded with it?

It’s been suggested. @bateske hasn’t done it, though.

One reason might be that the new bootloaders weren’t developed until after the Arduboy started shipping, so there might be logistical and support issues with having two versions out there. Plus, developers might tend to want to keep programs small enough to fit in the original version, to reach the largest audience, anyway.

Another factor would be thoroughly testing the new bootloader to make sure there were no unseen problems. You wouldn’t want to have to support a “recall” if a problem was discovered after many units were shipped. The installed standard “Catrina/Leonardo” bootloader is tried and tested over many products and units shipped.

It’s hard to say whether this is an advantage or disadvantage (from a business point of view):
If the smaller bootloader resulted in a large number of “oversize” Arduboy sketches being developed, people building “clones” from “off the shelf” Arduino (or compatible) boards would have to be able to burn the smaller bootloader to be able to run these large sketches.

I can understand that line of reasoning. Compatibility, customer support, logistics are important considerations.

However, I am sold at least on the 3K version. Is there a step-by-step how-to for switching over to the Cathy3K? The readme file does not go into the installation procedure.

You need to attach a suitable ICSP (In Circuit Serial Programmer) to the pads on the Arduboy circuit board. Burning the bootloader is the same as for any other Arduino.

I think @Mr.Blinky’s custom boards package may allow you to select the proper bootloader and have the fuses set properly.

The bytecode approach may be a good way to go. The Apple II had a similar problem, but with even more ROM constraint, so Steve Wozniak made a bytecode interpreter called SWEET16 to optimize 16-bit math code (https://en.wikipedia.org/wiki/SWEET16), at the cost of lower performance.

Now you have me sold. The Apple IIe was my first real computer. You have unleashed beautiful memories. :slight_smile: Now I have to seriously consider this approach. I think key is to find a limited set of primitives for my application.