docs: document bootloader OTA flow

This commit is contained in:
2026-04-29 18:04:28 +02:00
parent 06834a0cc0
commit 09c686d542
4 changed files with 110 additions and 72 deletions

View File

@ -0,0 +1,62 @@
# Bootloader OTA Operator Guide
This guide explains the Universal Shifters single-slot bootloader update flow in `abawo_bt_app`.
## App-Side Flow
1. Connect to the target button and open **Device Details**.
2. In **Firmware Update**, select a local raw application `.bin` with **Select Firmware**.
3. The app validates size and vector table before enabling the update.
4. Review file metadata: size, session id, CRC32, app start, image version, and reset vector.
5. Tap **Start Update** and keep the phone close to the button.
6. The app sends `EnterDfu` to the running application, waits for reset, and connects to `US-DFU`.
7. The app sends bootloader `START`; this erases the active app slot.
8. The app transfers offset-based frames and tracks bootloader `expected_offset`.
9. The app sends `FINISH`, waits for final OK, then waits for the bootloader reset.
10. Success is shown only after the updated app reconnects and status verification passes.
## Image Requirements
- File extension must be `.bin`.
- Image must be at least 8 bytes and no larger than `0x42000` bytes.
- Image bytes must start at application address `0x00030000`.
- Initial stack pointer must be aligned and within `0x20000000..=0x20010000`.
- Reset vector must have the Thumb bit set and point inside the image after the first two vector words.
- Flags are always `0`; encrypted/signed update flags are not supported by the current bootloader.
- Image version is currently sent as `0` unless a later packaging flow provides it.
## Operational Notes
- Single-slot update is destructive after bootloader `START`; the previous app is erased before image transfer.
- If transfer fails after `START`, recovery is through bootloader DFU or external reflash.
- Gear writes and **Connect Button to Bike** stay disabled while OTA is running.
- If BLE drops during transfer, retry promptly while the bootloader is still advertising `US-DFU`.
- Cancel after `START` sends bootloader `ABORT` and leaves the device in bootloader/recovery flow.
## Troubleshooting
| Symptom in app | Likely cause | Operator action |
| --- | --- | --- |
| Invalid stack pointer or reset vector | `.bin` is not a raw app image for `0x00030000` | Rebuild/export the application image from the correct linker layout. |
| Could not connect to bootloader DFU mode | Phone did not find `US-DFU` after app reset | Move closer, retry, and verify the device is advertising `US-DFU`. |
| Timed out waiting for bootloader DFU status | Status indication/read did not arrive | Reconnect to `US-DFU` and retry. |
| Bootloader status `bounds error` | Image length or app start rejected | Use a valid app image no larger than `0x42000` bytes. |
| Bootloader status `CRC error` | Full-image CRC did not match flash contents | Re-export or re-download the `.bin`, then retry. |
| Bootloader status `vector table error` | Bootloader rejected the written vector table | Rebuild firmware for app start `0x00030000`. |
| Bootloader status `flash error` | Flash erase/write/read failed | Retry once; if repeated, service or externally reflash the device. |
| Bootloader status `boot metadata error` | Bootloader could not persist boot metadata | Treat as service risk; retry reflash, then return device if repeated. |
| Updated app did not reconnect | New app did not boot/confirm or reconnect window expired | Scan for `US-DFU`; if present, retry OTA with a known-good image. |
| Updated app reconnected but verification failed | Normal app status read failed | Reconnect manually and verify status; retry only if the device is still in bootloader or unusable. |
Escalate with app logs, device identifier, firmware filename/hash, and observed bootloader status when a known-good image repeatedly fails.
## Manual QA Checklist
- [ ] Happy path: select valid `.bin`, enter bootloader, transfer, finish, reboot, reconnect, completed.
- [ ] Image validation: invalid extension, empty file, too-small file, too-large file, invalid SP, invalid reset vector.
- [ ] UI state gating: gear ratio save and trainer assignment remain disabled during OTA.
- [ ] Queue-full/status recovery: app sends `GET_STATUS` and resumes from returned offset.
- [ ] Cancel path: cancel after `START` sends `[ABORT, session]` and shows canceled state.
- [ ] Bootloader status errors: CRC/vector/flash/metadata statuses show actionable messages.
- [ ] Reconnect timeout: no updated app reconnect produces a clear failure message.
- [ ] Regression check: after successful update, status and firmware telemetry still load normally.