Add collapsible differential OTA example for Ikoka Stick

This commit is contained in:
mikecarper committed 2026-10-26 18:16:15 -07:00
1 parent 6f5acf4fbd
commit 195dca93e4
2 files changed
+87

No files matched your search

+84
View File
@@ -160,6 +160,90 @@ application update needs no copy of the old firmware.
This locally packaged application is unsigned and uses explicit manual
installation; the separate bootloader package remains signed.
<details id="differential-upgrade" markdown="1">
<summary>Optional: differential firmware upgrade (smaller download)</summary>
A differential update sends a patch from the Ikoka Stick's exact running
application to the new application. It can reduce LoRa transfer time. The
bootloader update in step 7 still uses the signed full bootloader package.
Prepare the new binary and full package above first. Use this option only
when you also have the **original application DFU ZIP for the firmware
currently running on the Ikoka Stick**. A matching version label or a rebuild
of the same commit is not enough. If that original file is unavailable, use
the full update above.
On **Ikoka Stick — Repeater Admin**, get its current identity:
```text
ver
ota self
```
Copy the original application DFU ZIP onto **Raspberry Pi** as
`downloads/ikoka-stick-33dbm-repeater-running.zip`. In the Pi terminal, paste
the 16-character `base_hash` from that fresh `ota self` reply when prompted:
```bash
read -r -p 'Current Ikoka Stick base_hash (16 hex characters): ' IKOKA_BASE_HASH
export IKOKA_BASE_HASH
python3 - <<'PY'
import hashlib, json, os, re, struct, zipfile
from pathlib import Path
expected = os.environ['IKOKA_BASE_HASH'].strip().upper()
assert re.fullmatch(r'[0-9A-F]{16}', expected), 'Invalid base_hash'
with zipfile.ZipFile('downloads/ikoka-stick-33dbm-repeater-running.zip') as archive:
app = json.loads(archive.read('manifest.json'))['manifest']['application']
image = archive.read(app['bin_file'])
trailer = image[-56:]
assert len(trailer) == 56 and trailer[:4] == b'EndF', 'Missing EndF'
assert struct.unpack_from('<I', trailer, 4)[0] == len(image) - 56
assert hashlib.sha256(image[:-56]).digest()[:8] == trailer[8:16], 'Body hash mismatch'
assert struct.unpack_from('<I', trailer, 20)[0] == 0xE5331F02, 'Wrong application target'
assert trailer[24:].rstrip(b'\0') == b'ikoka_stick_nrf_33dbm', 'Wrong board'
assert trailer[8:16].hex().upper() == expected, 'This is not the running firmware'
Path('inputs/ikoka-stick-33dbm-repeater-running.bin').write_bytes(image)
print('Exact running application confirmed:', expected)
PY
```
Stop if any check fails. Then build and check the **in-place** nRF52 delta:
```bash
motatool build \
--base inputs/ikoka-stick-33dbm-repeater-running.bin \
--fw inputs/ikoka-stick-33dbm-repeater.bin \
--patch-type in-place \
--out inputs/ikoka-stick-33dbm-repeater-delta.mota
motatool verify inputs/ikoka-stick-33dbm-repeater-delta.mota
motatool inspect inputs/ikoka-stick-33dbm-repeater-delta.mota
ls -lh serve/ikoka-stick-33dbm-repeater.mota inputs/ikoka-stick-33dbm-repeater-delta.mota
```
Check `codec_id` is `2 (detools-in-place)`, `base_hash` matches the live Ikoka
Stick, target is `E5331F02`, and the new version/hardware match the full
package. Let motatool derive the safe workspace from the firmware; do not
override its memory or target checks. Compare package sizes and keep the full
update if the delta is not smaller. `verify` checks the delta container's
integrity; it does not prove that you selected the running base image.
To serve the delta, replace the full application package in the serving
folder **before starting motatool**:
```bash
cp inputs/ikoka-stick-33dbm-repeater-delta.mota serve/ikoka-stick-33dbm-repeater.mota
```
Continue with steps 4–9. In step 8, choose the **application, delta** row and
use its own eight-character manifest ID with `ota pull <APP_MID8> flash`,
then `ota install` when ready. The target's `base_hash` must still match
immediately before that pull. Updating only the bootloader in step 7 leaves
the running application unchanged, so it does not invalidate the delta base.
After installation, check the same new firmware version and expected
post-install body hash printed earlier in step 3.
</details>
## 4. Identify the Station G2's USB port
On **Raspberry Pi — terminal**:
+3
View File
@@ -112,6 +112,9 @@ nav:
- Older releases: old-releases/index.md
- Test Results: test-results/index.md
markdown_extensions:
- md_in_html
theme:
name: material
logo: _assets/meshcore.svg