Files
roro9stack/site/content/guide/updates.md
T
twislaandClaude Opus 5.5 472f13260f
CI / build (pull_request) Successful in 2m6s
Site / build (pull_request) Successful in 11s
Updates: a download that breaks is carried on
When the connection breaks during a release download (issue #54), the
device waits up to a minute for Wi-Fi, asks for the rest of the file
with a Range request and carries on: the slot and the hash so far are
kept. It gives up after three tries in a row that bring nothing.
Nothing is kept across a restart.

Carrying on asks for 64 KB free, not 80: between two connections of an
install 78 KB is free, and the first attempt on the device was refused
for that. update damage cut now breaks every connection after n bytes.

Tried on the device: v0.23.0 installed over four connections, and a
download that brought nothing given up with nothing switched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0162FokPdvY2KsS4NBfwyWPk
2026-10-11 18:26:39 +02:00

5.3 KiB

+++ title = "Updates" description = "How the device updates itself from the project's releases, from the SD card or from a PC, and how it protects itself when an update goes wrong." weight = 14 [extra] tag = "Firmware" screens = ["update.png"] +++

Every update is one signed file (.ota). The device installs only a file signed with the project's key, so it cannot be tricked into installing anything else, whichever way the file arrives.

Settings → System → Firmware

The page shows the version running, its status, the address to push updates to over Wi-Fi, and:

  • Latest release: Enter (or c) asks the server and says v0.11.0 (new) or (current). Enter again opens the release: its version, date, size and the tag's message, with Install when it is newer.
  • Older releases: the last ten, newest first. Opening an older one offers to go back to it, with a different question.
  • On the SD card: the .ota files found in /updates, ready to install. Copy one there with a computer or the Storage App; the Storage App also opens an .ota file and says whether it would install.

An install needs Wi-Fi if it is a download. The new firmware is checked before anything is written (the signature after the first 160 bytes) and again at the end (the image's hash). Then the device restarts. It will wait up to 60 seconds if you are typing, so that a restart never eats a note.

A download that breaks (the Wi-Fi drops, the link is poor) is not started over: the device waits up to a minute for Wi-Fi to come back, asks the server for the rest of the file, and carries on from where it was, as often as it takes while each try brings something more. It gives up after three tries in a row that bring nothing, and then nothing is changed. If the device is switched off in between, the download starts from the beginning next time.

Check for updates

Settings → System → Check for updates is on by default. Once a day, with Wi-Fi up and the clock set, the device looks at the latest release and says v0.11.0 is out: see Settings > System > Firmware, once per version. It installs nothing by itself unless you ask for that (below), and it does not announce a version that already failed and rolled back on this device.

Install updates by itself

Settings → System → Install updates is When asked by default. Set to By itself, a newer release found by the daily check is installed without your going to the Firmware page:

  1. The device waits for a quiet moment: no key pressed for 2 minutes, and nothing a restart would cut short (a Track or a Capture recording, files being copied or received, an SSH session, a web share).
  2. It then asks on the screen, over whatever is open, and lights the screen if it was off: Update to v0.24.0?, with a count from 30 seconds.
  3. Cancel (or `) leaves things as they are until the next day's check. Accept, or no answer when the count ends, downloads the release, installs it and restarts.

Everything else is as for an install you ask for: the signature is checked before anything is written, the new firmware runs on Probation, and a version that rolled back on this device is not offered again. It needs Check for updates to be on.

Each update that held, whoever started it, and each one that was undone, is written with its date in /system/updates.log on the SD card.

Probation and Rollback

A newly installed firmware runs on Probation: it must boot, draw its screen, start its services and run 30 seconds without a crash, and reconnect Wi-Fi if that is configured (within 3 minutes), before it is confirmed for good. If it crashes or restarts, or cannot get Wi-Fi back, the device rolls back to the previous firmware by itself and says so.

Safe Mode

If a confirmed firmware crashes and restarts 3 times in a row, the device starts in Safe Mode instead: only Wi-Fi and firmware updates, so a fix can be installed without a cable. A normal restart leaves it.

IRC steps aside

A secure connection takes about 52 KB of memory at its peak, and IRC's own takes about 40 KB of the 107 KB there is. So a check or an install that you ask for makes IRC disconnect for the few seconds it takes, and reconnect afterwards. The daily check never does that: with IRC connected it waits for a moment when IRC is not, so if IRC stays connected for days the daily check does not run, and Latest release is the way to check.

How the connection is trusted

The connection to the project's server is checked against the two root certificates that Let's Encrypt's chains end in, not against the usual bundle of about 130 authorities. Whatever the connection, the update file's own signature decides what gets installed.

For developers

Updates can also be pushed from a PC over Wi-Fi, with scripts/flash.sh --ota <ip>, or put on the card with scripts/sd_put.sh: see the README. The firmware's console can be reached over Wi-Fi too: see The Debug Console.

The keys, as the device lists them

What Fn + h shows on these screens. These tables are generated from the firmware's own lists, so they are always the current ones.

{{ keys(scopes=["firmware", "firmware-release", "firmware-older"]) }}