UART-Based "Remote" Firmware Update Completed

A project log for QMesh: A LoRa-based Voice Mesh Network

Developing a synchronized, flooded mesh network to carry codec2-encoded voice over LoRa

Dan FayDan Fay 06/20/2021 at 05:350 Comments

The ability to update a QMesh device's firmware over a UART, which will enable remote firmware update, is complete. I can now update the QMesh firmware over a UART, including both a "wired" USB-to-UART adapter as well as over an HC-05 Bluetooth-to-UART module. Next, I'm working on setting up an ESP32 board to provide a Wi-Fi-to-UART bridge that will allow me to communicate with QMesh boards via a sockets interface.

Some things I learned along the way:

  1. Using gzip to compress firmware updates is fairly straightforward to do, so long as you have a POSIX-y stuff available like malloc() and various file operators. If you have all of this, working on a gzip'ed file isn't much different from working on a regular file. Do note, however, that zlib uses a significant amount of both RAM and ROM. As a result, I only have zlib built into the bootloader.
  2. Mbed OS makes it fairly easy to implement a bootloader. Since I decided to make a bootloader that was just the QMesh app with some functionality removed, it was fairly large, totaling 150-200KB. I have plenty of program flash, so this isn't a big deal, but it might be if I try to fit everything inside of a smaller device.
  3. You can use the watchdog timer to implement a fallback capability for a botched firmware update. Basically, set the watchdog timer to some relatively short time period that's long enough to allow the main firmware to boot up and disable or pet the watchdog. If the firmware update is botched and it doesn't boot, the watchdog timer will reboot the board back into the bootloader, where a golden firmware image can be loaded instead.
  4. Static analyzers are interesting and fairly useful. The easiest one to do is to just enable clang-tidy in Mbed Studio. It definitely forced me to clean up my C++ code. I also set up codechecker (which runs clang-tidy and the Clang Static Analyzer) as well as Facebook Infer. While these are more cumbersome to use, Facebook Infer did some deeper analysis of my code and managed to find some code where I wasn't closing files that I had already opened.

Hopefully, once I get the remote firmware stuff done, I'll have multiple solar-powered QMesh nodes that I can access and manage over Wi-Fi. This will make testing and improving the protocol much easier!