Display/GUI watchdog for the "backlight on, no picture" failure

On PoE sites the MIPI-DSI panel can lose its init on a supply dip while the
RK3566 keeps running; the UI may also hang or exit. Three layers:

- hardware watchdog: systemd RuntimeWatchdogSec=20s (system.conf.d)
- GUI: SdWatchdog pings systemd per swapped frame (WATCHDOG_USEC=30s, enabled
  by the binary so older versions run under the same unit) and writes
  run/qt.frame; buttontask.service gets Restart=always, NotifyAccess=main,
  TimeoutAbortSec=10s
- bt-displaywatch (root, buttontask-displaywatch.service): kernel DRM/DSI
  timeouts, eth link down->up (PoE dip hint), stale UI frames, restart storms
  -> panel re-init (stop UI, fb0 blank 4->0, start UI), repeated -> reboot
  (max 3/day, never during OTA); incident log in /var/log/buttontask/

Manual recovery: hold one finger 10 s in the bottom-left corner (panels are
single-touch). Delivered by OTA via bt-update sync_system; the web service
runs `bt-update sync-system` at start for devices updated by an older
bt-update.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-11-10 07:10:10 +00:00
co-authored by Claude Opus 5.5
parent 115879ab67
commit d71fa812da
18 changed files with 940 additions and 5 deletions
+33
View File
@@ -260,6 +260,39 @@ restarts both services, then runs a health-check: the web `/healthz` must answer
switches `current` back to the previous version and restarts. Progress is shown
live and is also readable in the app's **Обновление** page.
## Display / GUI watchdog
Targets "backlight on, no picture until power re-plug" (seen on PoE sites:
a supply dip can reset the MIPI-DSI panel while the RK3566 keeps running).
Three layers:
| Layer | What hangs | Detection | Action |
|---|---|---|---|
| Hardware watchdog (`system.conf.d/buttontask-watchdog.conf`) | kernel / systemd | `/dev/watchdog` not pinged for 20 s | board reset |
| `buttontask.service` + `SdWatchdog` | Qt GUI / render thread / GPU | no frame swapped for 30 s (`WATCHDOG=1` sent per real frame) | systemd kills + restarts the UI |
| `buttontask-displaywatch` (`bt-displaywatch`, root) | panel / DRM pipeline | kernel DRM/DSI timeouts; eth link down→up (PoE dip hint); UI restart storm; UI stuck stopping | panel re-init (stop UI → `fb0/blank` 4→0 → start UI); repeated → reboot (max 3/day) |
**Manual recovery on a dark screen:** hold **one finger for 10 s in the
bottom-left corner** (72×72 px; touch usually still works on a dark panel).
The corner is shielded by an empty MouseArea, so a button under it never
fires (and does not react to touches inside the corner). The panels in use are
single-touch (1 slot), hence no multi-finger gesture. Same from a
shell: `sudo /opt/buttontask/scripts/bt-displaywatch recover`.
**Incident log:** `/var/log/buttontask/display-incidents.log`
(`bt-displaywatch status`), also in the journal of `buttontask-displaywatch`.
At every boot it records whether the previous boot ended cleanly or abruptly
(power cut / hang), plus the last display/link kernel events of that boot.
Tunables (env in a unit drop-in): `DISPLAYWATCH_LINK_RECOVER=0` disables the
re-init on link flap; `DISPLAYWATCH_RECOVER_GAP`, `..._RECOVER_MAX`,
`..._RESTART_MAX`, `..._REBOOT_MAX` — see the script header.
Delivered by OTA: `bt-update` installs the units and the watchdog config
(`sync_system`); on devices whose OTA ran an older `bt-update`, the web service
runs `bt-update sync-system` at start. A changed `buttontask.service` applies
to the UI from its next restart (or reboot).
## LCD brightness
Web UI → **Система** → «Яркость экрана», or the on-device settings menu.