bootloader with automatic sketch/program switching from SD card

one of the biggest drawbacks of arduino (and microcontrollers in general) is the small program storage. if you include a few libraries like TFT, FAT, Ethernet, you easily exhaust most of your program flash memory (70%). this really hurts.

but there is an SD card. lots of space. gigabytes instead of kilobytes. unfortunately, you cannot run the program from there.

so, the objective is to utilize SD card as a storage for programs, with these information taken into account:

  • programs can be run only from flash memory
  • copying program from SD to flash can be done in the bootloader (2boots and such)
  • but 2boots is made for manually triggered in-the-field program replacement
  • the loop() method actually gets called by the bootloader

is there a way to programatically trigger .hex file upload/replacement, while this .hex file's filename is received from inside the current program's loop() ? i believe there is.

the sketch's loop calling is implemented in the bootloader.
so i assume there is something like this in the bootloader:

    while(true)
    {
        call_sketch_loop();
    }

can it be changed to this? :

    //signature changed from void loop() to int loop()
    while(true)
    {
        int retval = call_sketch_loop(); //get loop call's return value
        
        if( 0 == retval )
            continue; // if 0, iterate the loop as usual
        else
        {
            //copy 1.HEX from sd to flash and reboot
            copy_hex_from_sd_to_flash( retval + ".HEX" );
            reboot();
        }
    }
  • change loop singature to int loop()
  • put {int}.HEX files to an SD card - 1.HEX , 2.HEX , 3.HEX
  • the loop() call returns 0
  • continue with next iteration as usual
  • the loop() call returns 2
  • copy file 2.HEX from SD card into program flash memory
  • reboot device

with this approach, you can run flash-capacity-exceeding programs if you split them into smaller subprograms. you are no longer limited by the program size.

can this be done or not?

I like the idea!

kor3k:
the loop() method actually gets called by the bootloader

I don't think it works that way

Why not just do it like this:
From https://github.com/thseiler/embedded/tree/master/avr/2boots:

you will have to give
your board a name. For this, simply load the included Sketch
"NameBoardSketch.pde", optionally edit the name, and then run the sketch.
The sketch simply writes that name to the end of the EEPROM, in inverse order.
IMPORTANT: The name you choose must be a MS DOS compatible name. This means:

  • The name can not be longer than 8 characters.
  • The name must contain only UPPER CASE letters. Not lower case allowed, as
    MS DOS converts them to upper case before saving.
    The default name in NameBoardSketch.pde is a simple "ARDUINO".

Now, prepare an SD card with the first partition: FAT16 and less than 2GB
in size. Copy the hex file directly into the root folder of the SD Card
and give it the same name as your board: i.e. ARDUINO.HEX.

So lets say you have multiple different programs on your SD card that you want to run depending on different conditions. To switch programs you only need to:

  • Write the desired program filename to EEPROM
  • Reset the MCU using the watchdog

Now the problem with that is many bootloaders only are run on hard reset, I haven't used 2boots so I don't know if this is the case but it should be easy to modify it to run on every reset.

Another option for an SD bootloader is GitHub - zevero/avr_boot: Arduino Bootloader to Flash from SD Card. This one doesn't read the filename from EEPROM so the program switching procedure would be:

  • Delete FIRMWARE.bin
  • Copy the desired program file to FIRMWARE.bin
  • Reset the MCU using the watchdog