Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b9500356b0 | |||
| 35cd6b7230 |
@@ -58,7 +58,16 @@ software-render → `/run/shturman/splash.png`, `Before=shell` → до перв
|
|||||||
`After=shell`); общий рендер-хелпер `shturman-render` (shell+splash). `just vm-reset && just e2e` зелёный с нуля:
|
`After=shell`); общий рендер-хелпер `shturman-render` (shell+splash). `just vm-reset && just e2e` зелёный с нуля:
|
||||||
фазы разделены (splash ≤ frame ≤ stage2), регресс v0.1/v0.6 цел. Приёмка спека v0.2 §9.3 выполнена.
|
фазы разделены (splash ≤ frame ≤ stage2), регресс v0.1/v0.6 цел. Приёмка спека v0.2 §9.3 выполнена.
|
||||||
|
|
||||||
**Следующее:** `v0.3` power-safe и `v0.5` полный shell (живой weston-shell) — параллельно поверх v0.2 · затем `v0.4` MCU/thermal.
|
**v0.3 Power-safe ядро — ГОТОВО (ветка `feat/v0.3-power-safe`):** спека `docs/specs/v0.3-power-safe.md` + план
|
||||||
|
`docs/specs/plans/07-v0.3-power-safe.md`. Стаб `Power` → **реальный lifecycle-FSM**: чистый `PowerFsm`
|
||||||
|
(`off↔accessory↔running→shutting_down{abortable→committed}→off`, abort до PONR) + сервис `ru.shturman.Power`
|
||||||
|
оживлён из FSM (dev-mock кормит события, grace-таймер + durable-barrier `sync` на commit); watchdog-конфиг (B05/A14) +
|
||||||
|
save-time timer (B07). `just vm-reset && just e2e` зелёный с нуля: **N=3 цикла зажигания** (`/data` + счётчик целы),
|
||||||
|
**abort до PONR** (`ShutdownAborted`, `/data` RW, running), **power-cut-сим** (SIGKILL → `fsck` clean, durable-value цел);
|
||||||
|
регресс v0.1/v0.2 + machine-id-стабильность цел. prod-build-gate: `--no-default-features` без `PowerMock1`. Приёмка спека
|
||||||
|
v0.3 §9.4 выполнена. **VM-модель** (abort/PONR = stop+umount+remount); аппаратное (MCU/hold-up/fail-safe-таймер, **B08/B09**) → v0.4.
|
||||||
|
|
||||||
|
**Следующее:** `v0.5` полный shell (живой weston-shell) и `v0.4` MCU/thermal (замыкает B08/B09) — параллельно поверх v0.2/v0.3.
|
||||||
|
|
||||||
> CI: GitHub-Actions-конфиг **удалён** (его ловит Gitea). Гейт — локальный `just ci`. CI на Gitea — решение позже.
|
> CI: GitHub-Actions-конфиг **удалён** (его ловит Gitea). Гейт — локальный `just ci`. CI на Gitea — решение позже.
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,7 @@
|
|||||||
- **Методы:** `GetPowerState() → state` (enum `off`/`accessory`/`running`/`shutting_down`/`sleep`/`battery_cutoff`), `RequestSleep()` (внутр.).
|
- **Методы:** `GetPowerState() → state` (enum `off`/`accessory`/`running`/`shutting_down`/`sleep`/`battery_cutoff`), `RequestSleep()` (внутр.).
|
||||||
- **Сигналы:** `AccChanged(on)`, `ShutdownImminent(seconds, reason)` (`reason ∈ acc_off|under_voltage|thermal|battery_cutoff`), **`ShutdownAborted()`** (re-power до PONR), `Sleep()`, `Wake()`.
|
- **Сигналы:** `AccChanged(on)`, `ShutdownImminent(seconds, reason)` (`reason ∈ acc_off|under_voltage|thermal|battery_cutoff`), **`ShutdownAborted()`** (re-power до PONR), `Sleep()`, `Wake()`.
|
||||||
- **Properties:** `IgnitionState` (off/accessory/running — **канон**; E зеркалит, не дублирует), `Uptime` (монотонные часы), `PowerSource` (`vehicle_12v`/`holdup_cap`/`sleep_rail`/`low_battery`).
|
- **Properties:** `IgnitionState` (off/accessory/running — **канон**; E зеркалит, не дублирует), `Uptime` (монотонные часы), `PowerSource` (`vehicle_12v`/`holdup_cap`/`sleep_rail`/`low_battery`).
|
||||||
|
- **Реализация (v0.3):** состояние/сигналы **оживлены из FSM** (`PowerFsm` в `shturman-power`, не mock); `ShutdownImminent`/`ShutdownAborted` — из реальных переходов (abort до PONR + grace-таймер). `Sleep`/`Wake`/`RequestSleep` объявлены, но **зарезервированы** (v1/v2, B §7). Источник событий (ACC/voltage/thermal через MCU) → v0.4; в v0.3 кормит dev-mock.
|
||||||
|
|
||||||
### `ru.shturman.Settings` — конфигурация и состояние
|
### `ru.shturman.Settings` — конфигурация и состояние
|
||||||
- **Методы:** `Get(key) → value`, `Set(key, value)`, `List(prefix) → [key]`, `Reset(key)`.
|
- **Методы:** `Get(key) → value`, `Set(key, value)`, `List(prefix) → [key]`, `Reset(key)`.
|
||||||
|
|||||||
@@ -7,6 +7,12 @@
|
|||||||
Статус: **v2 (на ревью).** v2 — после adversarial-ревью (22 находки).
|
Статус: **v2 (на ревью).** v2 — после adversarial-ревью (22 находки).
|
||||||
Связано с: [architecture.md](../architecture.md) (§6) · [hardware.md](../contracts/hardware.md) (§3 питание/MCU) · [a-base-system.md](a-base-system.md) (§5–§11) · [ipc.md](../contracts/ipc.md) (`Power`) · [principles.md](../principles.md) (#5) · домены D (гейт wake-word), E (engine-state)
|
Связано с: [architecture.md](../architecture.md) (§6) · [hardware.md](../contracts/hardware.md) (§3 питание/MCU) · [a-base-system.md](a-base-system.md) (§5–§11) · [ipc.md](../contracts/ipc.md) (`Power`) · [principles.md](../principles.md) (#5) · домены D (гейт wake-word), E (engine-state)
|
||||||
|
|
||||||
|
**Реализация (v0.3):** срезы **B01–B07** реализованы — чистый `PowerFsm` (§2: `off↔accessory↔running→shutting-down
|
||||||
|
{abortable→committed}→off`, abort до PONR) + сервис `ru.shturman.Power` оживлён из FSM (grace-таймер + durable-barrier
|
||||||
|
`sync` на commit), watchdog/save-time-конфиг. **VM-модель:** abort/PONR в Lima = stop+umount+remount, power-cut =
|
||||||
|
SIGKILL+`fsck`. Аппаратное (MCU/hold-up/heartbeat/`safe-to-cut`/fail-safe-таймер) и выбор **B08/B09** → **v0.4**;
|
||||||
|
sleep/wake/battery-cutoff — каркас (no-op), тело → v1/v2 (§7). Спека: `docs/specs/v0.3-power-safe.md`.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 1. Назначение и границы
|
## 1. Назначение и границы
|
||||||
@@ -193,8 +199,8 @@ power-эффектом; ни одно SoC-сообщение не должно (
|
|||||||
|
|
||||||
## 12. Открытые вопросы
|
## 12. Открытые вопросы
|
||||||
|
|
||||||
- 🟡 **MCU-копилот vs supercap-only** (hardware §3) — определяет владельца ACC/watchdog, **наличие
|
- 🟡 **MCU-копилот vs supercap-only** (hardware §3, **B08/B09**) — определяет владельца ACC/watchdog, **наличие
|
||||||
независимого бэкстопа и fail-safe-снятия при зависшем SoC**, и доступность scheduled-wake.
|
независимого бэкстопа и fail-safe-снятия при зависшем SoC**, и доступность scheduled-wake. **→ v0.4** (вероятно нужна аппаратная проверка).
|
||||||
- ◻️ **Протокол SoC↔MCU** (UART/I2C/GPIO, формат, keepalive, политика тишины-линка, replay-защита) —
|
- ◻️ **Протокол SoC↔MCU** (UART/I2C/GPIO, формат, keepalive, политика тишины-линка, replay-защита) —
|
||||||
shutdown-подмножество уже специфицировано в §4/§5, остальное здесь.
|
shutdown-подмножество уже специфицировано в §4/§5, остальное здесь.
|
||||||
- ◻️ **Бюджет разряда АКБ** (sleep, ACC-off listening, battery-cutoff порог) — числа с hardware.
|
- ◻️ **Бюджет разряда АКБ** (sleep, ACC-off listening, battery-cutoff порог) — числа с hardware.
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ shturman/
|
|||||||
`dbus-daemon`) — герметично, параллелизуемо, без root (§9).
|
`dbus-daemon`) — герметично, параллелизуемо, без root (§9).
|
||||||
- Изоляция песочных апов — через прокси (появится с App-Host, v3).
|
- Изоляция песочных апов — через прокси (появится с App-Host, v3).
|
||||||
|
|
||||||
### 5.2 `ru.shturman.Power` — стаб (B04, домен B §9)
|
### 5.2 `ru.shturman.Power` — стаб v0.1 → **реальный FSM v0.3** (B03/B04, домен B §9)
|
||||||
|
|
||||||
- **Имя/путь/интерфейс:** `ru.shturman.Power` · `/ru/shturman/Power` · `ru.shturman.Power1`.
|
- **Имя/путь/интерфейс:** `ru.shturman.Power` · `/ru/shturman/Power` · `ru.shturman.Power1`.
|
||||||
- **Методы:**
|
- **Методы:**
|
||||||
@@ -258,11 +258,13 @@ shturman/
|
|||||||
- `IgnitionState: s` ∈ `{off, accessory, running}` — **канон** (B §1; E зеркалит, не дублирует)
|
- `IgnitionState: s` ∈ `{off, accessory, running}` — **канон** (B §1; E зеркалит, не дублирует)
|
||||||
- `Uptime: t` — секунды **монотонных** часов (`CLOCK_MONOTONIC`, B §8)
|
- `Uptime: t` — секунды **монотонных** часов (`CLOCK_MONOTONIC`, B §8)
|
||||||
- `PowerSource: s` ∈ `{vehicle_12v, holdup_cap, sleep_rail, low_battery}`
|
- `PowerSource: s` ∈ `{vehicle_12v, holdup_cap, sleep_rail, low_battery}`
|
||||||
- **Стаб-поведение (v0):** старт в `running`/`IgnitionState=running`/`PowerSource=vehicle_12v`;
|
- **Поведение:** старт в `running`/`IgnitionState=running`/`PowerSource=vehicle_12v`; `Uptime` растёт монотонно.
|
||||||
`Uptime` растёт монотонно. **Никаких** методов записи/actuator (#2). Реальная FSM/секвенсинг — v0.3.
|
**Никаких** методов записи/actuator (#2). **v0.1 — плоский стаб; v0.3 — реальный `PowerFsm`** (состояния/переходы B03,
|
||||||
|
graceful shutdown подход A, grace-таймер + durable-barrier `sync` на commit/PONR); `power_state`/`ignition`/`source` —
|
||||||
|
проекции FSM. Реальный источник событий (ACC/voltage/thermal через MCU) → v0.4; в v0.3 события кормит dev-mock.
|
||||||
- **Dev-mock (feature `dev-mocks`):** доп.интерфейс `ru.shturman.dev.PowerMock1` на том же объекте —
|
- **Dev-mock (feature `dev-mocks`):** доп.интерфейс `ru.shturman.dev.PowerMock1` на том же объекте —
|
||||||
«**fake-ACC**» для тестов и будущего v0.3:
|
«**fake-ACC/voltage/thermal**», **кормит входы FSM** (v0.3) для тестов/E2E:
|
||||||
- `SetAcc(b on)` → меняет state/IgnitionState + эмитит `AccChanged`
|
- `SetAcc(b on)` → `Event::AccOn`/`AccOff` (FSM) + эмитит `AccChanged`
|
||||||
- `SetIgnition(s state)`
|
- `SetIgnition(s state)`
|
||||||
- `TriggerShutdown(u seconds, s reason)` → эмитит `ShutdownImminent`
|
- `TriggerShutdown(u seconds, s reason)` → эмитит `ShutdownImminent`
|
||||||
- `AbortShutdown()` → эмитит `ShutdownAborted`
|
- `AbortShutdown()` → эмитит `ShutdownAborted`
|
||||||
|
|||||||
+13
-3
@@ -199,6 +199,9 @@ echo " $(systemd-analyze time 2>/dev/null | head -1 || echo 'systemd-analyze н
|
|||||||
# ---- power-safe (v0.3): FSM ShutdownImminent + N циклов зажигания + abort + power-cut ----
|
# ---- power-safe (v0.3): FSM ShutdownImminent + N циклов зажигания + abort + power-cut ----
|
||||||
info "power-safe: ShutdownImminent + N=3 цикла зажигания + abort + power-cut"
|
info "power-safe: ShutdownImminent + N=3 цикла зажигания + abort + power-cut"
|
||||||
# Чистый FSM Running для циклов (свежий бинарь + сброс любого «залипшего» состояния от §5 fake-ACC).
|
# Чистый FSM Running для циклов (свежий бинарь + сброс любого «залипшего» состояния от §5 fake-ACC).
|
||||||
|
# reset-failed: блок ниже намеренно рестартит power N+ раз — сбрасываем счётчик StartLimitBurst (дефолт 5/10s),
|
||||||
|
# иначе systemd ловит start-limit-hit и power падает в failed (имя ru.shturman.Power на шине теряется).
|
||||||
|
sudo systemctl reset-failed shturman-power.service shturman-settings.service 2>/dev/null || true
|
||||||
sudo systemctl restart shturman-power.service
|
sudo systemctl restart shturman-power.service
|
||||||
for _ in $(seq 1 10); do systemctl is-active --quiet shturman-power && break; sleep 1; done
|
for _ in $(seq 1 10); do systemctl is-active --quiet shturman-power && break; sleep 1; done
|
||||||
sleep 1 # дать power re-acquire ru.shturman.Power на шине
|
sleep 1 # дать power re-acquire ru.shturman.Power на шине
|
||||||
@@ -223,8 +226,13 @@ for i in 1 2 3; do
|
|||||||
sudo umount /etc/machine-id 2>/dev/null || true # снять machineid-bind, иначе /data busy
|
sudo umount /etc/machine-id 2>/dev/null || true # снять machineid-bind, иначе /data busy
|
||||||
sync; sudo umount /data || fail "цикл $i: umount /data (PONR)"
|
sync; sudo umount /data || fail "цикл $i: umount /data (PONR)"
|
||||||
findmnt /data >/dev/null && fail "цикл $i: /data не размонтирован (PONR не достигнут)"
|
findmnt /data >/dev/null && fail "цикл $i: /data не размонтирован (PONR не достигнут)"
|
||||||
sudo systemctl start shturman.target # re-mount data.mount + сервисы (machineid re-bind)
|
sudo systemctl reset-failed shturman-power.service shturman-settings.service 2>/dev/null || true
|
||||||
for _ in $(seq 1 15); do systemctl is-active --quiet shturman-settings && break; sleep 1; done
|
sudo systemctl start shturman.target # re-mount data.mount + сервисы
|
||||||
|
# machineid — oneshot RemainAfterExit (уже active): plain start его НЕ перезапускает, bind не вернётся.
|
||||||
|
# restart форсит ExecStart → пере-bind /data/state/machine-id поверх снятого выше. Без этого /etc/machine-id
|
||||||
|
# залипает на нижнем rootfs-значении, и POST-чек стабильности machine-id (§9.3.4) падает после reboot.
|
||||||
|
sudo systemctl restart shturman-machineid.service
|
||||||
|
for _ in $(seq 1 15); do systemctl is-active --quiet shturman-settings && systemctl is-active --quiet shturman-power && break; sleep 1; done
|
||||||
findmnt /data >/dev/null || fail "цикл $i: /data не вернулся после remount"
|
findmnt /data >/dev/null || fail "цикл $i: /data не вернулся после remount"
|
||||||
echo "$n" | sudo tee /data/state/power-cycles >/dev/null
|
echo "$n" | sudo tee /data/state/power-cycles >/dev/null
|
||||||
pass "цикл зажигания $i: stop→umount(PONR)→remount→restart, /data вернулся"
|
pass "цикл зажигания $i: stop→umount(PONR)→remount→restart, /data вернулся"
|
||||||
@@ -254,8 +262,10 @@ sudo umount /etc/machine-id 2>/dev/null || true
|
|||||||
sudo umount /data 2>/dev/null || sudo umount -l /data 2>/dev/null || true
|
sudo umount /data 2>/dev/null || sudo umount -l /data 2>/dev/null || true
|
||||||
findmnt /data >/dev/null && fail "power-cut: /data не размонтирован (fsck был бы на смонтированном)"
|
findmnt /data >/dev/null && fail "power-cut: /data не размонтирован (fsck был бы на смонтированном)"
|
||||||
sudo fsck.ext4 -n /var/lib/shturman/data.img >/dev/null 2>&1 || fail "fsck /data не clean после power-cut"
|
sudo fsck.ext4 -n /var/lib/shturman/data.img >/dev/null 2>&1 || fail "fsck /data не clean после power-cut"
|
||||||
|
sudo systemctl reset-failed shturman-power.service shturman-settings.service 2>/dev/null || true
|
||||||
sudo systemctl start shturman.target # re-mount + restart
|
sudo systemctl start shturman.target # re-mount + restart
|
||||||
for _ in $(seq 1 15); do systemctl is-active --quiet shturman-settings && break; sleep 1; done
|
sudo systemctl restart shturman-machineid.service # пере-bind machine-id (plain start не перезапускает oneshot — см. цикл)
|
||||||
|
for _ in $(seq 1 15); do systemctl is-active --quiet shturman-settings && systemctl is-active --quiet shturman-power && break; sleep 1; done
|
||||||
sudo grep -q night /data/settings/settings.json || fail "last durable value потерян после power-cut"
|
sudo grep -q night /data/settings/settings.json || fail "last durable value потерян после power-cut"
|
||||||
pass "power-cut-сим: /data консистентен (fsck clean, night present)"
|
pass "power-cut-сим: /data консистентен (fsck clean, night present)"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user