Forgetfulino Puts Back Up Of Source Inside The Binary

How often have you pulled out old MCU-based project that still works fine, but you have no idea where the original source code has gone? Having the binary image and the source code as separate things to keep track of usually isn’t a problem, but there’s something to be said for adding the source — and documentation — to this image if you have some flash to spare. This is basically what the Forgetfulino Arduino library by [Nader Al Khatib] does.

Essentially, the library compresses the source files and assigns it to be burned onto the flash alongside the binary. There is also a bit of code added to the firmware so that this code can be retrieved via the serial port at any time, negating the need for a firmware dump and manual disassembly. For ease of use, the library has an Arduino IDE extension that automates the process. The basic idea could also be adapted to different environments should anyone wish to take up the challenge.

You probably wouldn’t want debug builds to feature this additional payload as writing it to flash will eat up time and write cycles. But for a release build that will be put out in the (literal) field for a few years or even decades, it could be very convenient. After all, you never know when that Git repository that you relied on might go AWOL.

24 thoughts on “Forgetfulino Puts Back Up Of Source Inside The Binary

  1. Another reason why I’ve mostly moved to micropython for hobby projects. The code is just on the board by design. And with $5 RP2040 and ESP32 boards that run micropython there is no reason not to except when you need more speed then it can provide, which is rare.

    1. These days we get so powerful chips for peanuts that they can run high level interpreter like Micropython and still do some heavy lifting in the background, on a second core or with PIO, DMA and other peripherals. Like driving LED matrices with 16k RGB LEDs that have no onboard memory or running as ROM/RAM emulator while examining the memory contents live. And still have plenty of free unused space.

    2. Agree. I haven’t found anything yet that ‘I’ do that requires more speed. Python handles it. And as you say, you can always get the source code back off the device. That said, all my projects are on the home server and periodic backups are made local and off-site, so losing data would be pretty hard. Of course you still need to know what ‘folder’ you put it in after a few years! Ha!

      That said I am about to embark on kicking around freeRTOS on RP2350 boards. Get back to my ‘C’ roots for fun.

      1. You must not be doing any real-time control or power electronics control, I can’t remember my last project where the difference in real-time performance would have been feasible.

        I’d like to play with that some time, but my projects (both professional and hobby) rarely allow for such decadence.

        1. You are right, not any more anyway! Those days are gone when I was doing RT SCADA apps for RTUs and Plant Control Systems with VRTX and other RT modules using assembly and C. Now, At home motor on, motor off, move a servo, door open, door closed, light switch on/off type inputs, read the temperature, read a distance measurement, etc… that don’t need precise response times to events. At work I am working with energy management systems which run on Windoze. It is in real-time … but not as how real-time is defined down in the SCADA IED/RTU world for control like syncing a breaker to the grid, or load shedding when an event occurs…. I do remember those fun days…

  2. There is an amazing amount of flash on a cheap NodeMCU, but I don’t know that I am forgetful enough to use this feature. I’d be concerned about mysterious dredged-up source finding its way into places it doesn’t belong. I’ve been excited, though, to put LittleFS file systems on it for locally storing sensor data when the internet disappears.

  3. That is a great idea. I haven’t been burned by this as I put my stuff on github and have used the same laptop for microcontroller work for the last few years, but I could see the younger me getting crushed by losing the source.

  4. In the early 2000s I was working on a piece of very flawed (recently manufactured at the time) Nortel hardware. A friend of mine had worked on this in the 80s. I asked if he had the source code, and he told me it was exactly this. Just tagged onto the end of the firmware.

  5. This is a really good idea. My attempt at same was to put the (cloud) URL to the source code in a Serial.Print statement in the setup{}. But I’m not nearly as diligent as I should be.

    I have definitely been bit by this.

    1. What a stupid point of view. Try explaining to a field technician in the middle of nowhere, with no internet and a dying laptop, that they “don’t deserve” to recover the code from a device because you forgot to push to GitHub or you made an evaluattion hardware mistake uploading it. While you’re sipping your artisanal coffee in your climate-controlled office, and they’re staring at a broken irrigation system that’s flooding a field.

      1. yeah so .. Zaza is responding to the article, and the title ‘forgetfulino’. for many of us, it’s hard to imagine losing source code…i personally haven’t lost any source since about 1996 (16yo). but yeah the technique is valuable for totally different scenarios than forgetfulness!

    2. How delightfully naive.

      Two small examples at each end of the spectrum –

      1) A home hobbyist with no professional experience is unlikley to be versed in the nuances of version control and code management. Why does someone learning, expanding their mind, having fun with technology not “deserve” anything that helps them to continue learning? Does an apprentice mechanic not “deserve” any more than a single screwdriver until they somehow earn the right to more tools?

      2) A professional coder with decades of experience might be very well versed in all of the code management needed, and still find this technique to be a clean, less dependant way to distribute a learning code kit to schools or similar. They might have all the tools in the world available to them and know exactly how to use them, and yet still use this idea/library because it suits a need.

  6. At my work we’ve been doing something similar for quite long while, though, simpler than that, zipping entire source code and embedding it in the MS Word technical documentation. Most projects are quite small, and almost always .NET code, and even with all the addons/DLLs are perfectly fine living there.

  7. If you don’t have that luxury then you could fine tune LLM4Decompile to target other, embedded, platforms where there is a lot of FOSS code available.

    Take as much working AVR source code from the web as possible then compile it to bin files then use a decompiler on them, then take the three datasets, Source, Bin (hex dumps), and Decompiled code then fine tune a FOSS Agentic and reasoning LLM on that data so that it knows how do the reverse association from Hex Dump back to most probable source code. A reverse engineering agent on steroids.

  8. Neat idea.
    A quick scan of the docs seems that it stores only your local source files. Not all the associated libraries. So it’s still up to the archeologist who recovers that source, to also chase down all the associated libraries, with the correct versions. Probably the build environment too.
    Nice to see it auto-comments the version numbers at least.

    1. Embedding all the libraries would made everything explode, this is a backup plan, not a day to day use, so if the archivist needs to re-download 5 libraries I dont think it’s a great deal, I think he made the right choice integrating only the important things on the device. And if you really fear that ww3 will wipe out the git library you can allways insert them in the document and upload them with the tool.

  9. For Arduino, I do this:
    include this liine
    #include “printme.h”
    in the source, and a command
    PRINTME();
    somewhere in the code.

    Then a script print.sh generates printme.h:
    awk ‘BEGIN{print “void PRINTME() { Serial.write(\”\”}{gsub(/\/,”\\”);gsub(“\””,”\\””);print $0 “\n\”}END{print “\”);}”}’ *.ino > printme.h

Leave a Reply

Please be kind and respectful to help make the comments section excellent. (Comment Policy)

This site uses Akismet to reduce spam. Learn how your comment data is processed.