Saving flash question

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.

https://www.arduino.cc/en/hacking/bootloader

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.

If you’re interested in bytecode then you might like this old unfinished project of mine:

The bytecode I came up with was fairly general purpose.
I purposely made it stack-based and used variable length opcodes because they both lead to denser bytecode.

If you had an FX chip though, you might be better off creating something more special purpose that uses larger bytecode in order to reduce the on-chip size of the bytecode interpreter.

Bear in mind that bytecode has an overhead that may eat into your processing time.

I’d definitely recommed trying this.

As others will tell you, graphics are often one of the things that most eat into progemem.
That’s one of the reasons people have developed other font libraries that offer a smaller set of characters and sometimes smaller fonts.

I would need some help flashing the Cathy2K bootloader on the Arduboy. I am using avrdude from the command line. From what I understand I first need to write the fuse bits and then write the bootloader hex file. What I am not clear about are the values for the fuse bits. These are values I have found online but I don’t think these will work for the Arduboy

avrdude -U efuse:w:0x05:m -U hfuse:w:0xD6:m -U lfuse:w:0xFF:m

Then after that I do

avrdude -e -Uflash:w:arduboy2k-bootloader.hex

Reading the fuse bits of my Arduboy I get:

lfuse: FF
hfuse: D8
efuse: CB

This is for a boot flash size of 2k words. Setting it to 1k words, which is required for the Cathy bootloader, changes the hfuse from D8 to DA. Do I have this right? So I should first set the fuses to
lfuse: FF, hfuse: DA, efuse: CB

I have managed to flash the Cathy3k bootloader onto the Arduboy. (Couldn’t get the Cathy2k working). But when I use the IDE to upload a new sketch it still shows me Maximum is 28672 bytes. Shouldn’t that be more by one 1k?

The maximum program size is defined in the boards.txt file associated with the board type, and possibly other settings for that board, you’ve chosen in the IDE. @Mr.Blinky provides a boards package in his Arduboy homemade package repository that would allow you to select a board corresponding to the hardware and bootloader you’re using.

This package also contains the proper fuse settings for use with the Cathy bootloaders.

You could also modify an existing boards.txt file or create your own custom board package.

Great! I have installed the “Arduboy homemade” package and everything seems to be working fine so far. But I only see Cathy3k. Does this not support Cathy2k?

I haven’t looked too closely at the package. Perhaps @Mr.Blinky can chime in here?

the Cathy2K bootloader is not available in the Homemade package 1.2.9. Will be back in 1.3.0. But until then you can revert to version 1.2.8 of the package to use Cathy2K

1 Like