77d9a5a0ee
Новый домен H (медиа/аудио). Ядро — сквозной арбитр аудио (политика фокуса/ducking поверх PipeWire, role-based), плюс медиаплеер (локальное/BT A2DP/AVRCP/радио/стриминг). Многоагентный adversarial-ревью: 24 находки, 20 подтверждено (default-refute), все применены. Ключевое из ревью: - symphonia НЕ декодирует Opus → отдельный audiopus (libopus, BSD). - AEC: module-echo-cancel (≠ filter-chain) в audio-plane, не в ассистенте — резолв D §147. - media.role (арбитраж) vs media.category (Playback/Capture) разведены. - Кнопки громкости мультируля — uinput→Wayland-input (C/K), не интенты ассистента. - Crash-safe по двум осям (source: жизнь ноды + проактивный cork по NameOwnerChanged/watchdog; sink: пересчёт при возврате output). - intra-role media-фокус (один media-продюсер), гистерезис фокуса (анти-pumping), duck = относит. аттенюатор. - boot аудио-плоскости на Stage 1; отказ-пути плеера (битый файл/обрыв A2DP/ENOSPC/underrun); resume без авто-старта. Кросс-док: D §147 AEC→✅; tech-stack (symphonia/audiopus/module-echo-cancel); hardware §4 (amp-mute-GPIO + FM-тюнер + откр. вопросы); B §4 (amp-mute перед cut); architecture §9 (аудио-арбитр → H); domains/README (строка H). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
180 lines
16 KiB
Markdown
180 lines
16 KiB
Markdown
# Контракт: железо и board-support
|
||
|
||
> Целевой таргет, топология питания, периферия — и **HAL/BSP** для портирования под
|
||
> другое железо/авто (то самое «API для автопроизводителей/автолюбителей» из vision).
|
||
|
||
Статус: **v2 (на ревью).** v2 — после ретро-ревью (8 находок).
|
||
Связано с: [architecture.md](../architecture.md) · [dev-environment.md](../dev-environment.md) · [data-model.md](data-model.md) (§7 DBC) · [security-privacy.md](security-privacy.md) (якорь доверия) · домены A/B/E/J/K
|
||
|
||
---
|
||
|
||
## 1. Целевой SoC
|
||
|
||
**RK3588 / RK3588S класс, 8–16 ГБ RAM.** Почему: приличная mainline-Linux-поддержка,
|
||
Panfrost GPU, мощности хватает на плавный UI и **локальную мелкую LLM**; это же класс
|
||
реальных автоголов.
|
||
|
||
## 1a. Тепловой и механический конверт 🟡
|
||
|
||
- **Конверт температур (цель):** работа ~−20…+70 °C, выживание/хранение ~−40…+85 °C —
|
||
под автомобильные крайности (солнечный нагрев салона; зимний холод).
|
||
- **Температурный класс** SoC-модуля и eMMC: industrial (−40…+85, AEC-Q100) **или** явно
|
||
принять consumer-риск для reference с письменным обоснованием + caveat по retention eMMC.
|
||
- **Холодный старт** (eMMC + DDR) при минимуме конверта — тест-кейс −30 °C.
|
||
- **Охлаждение:** пассив (радиатор) vs актив — против worst-case sun-load (RK3588 горячий). 🟡
|
||
- Софтовый throttling (a-base §10) это **не** заменяет — он не лечит отсутствие конверта/класса.
|
||
|
||
## 2. Хранилище
|
||
|
||
- **eMMC** — rootfs, **read-only**.
|
||
- **Раздел `/data`** — read-write, **журналируемый**. Тип ФС + контракт записи — [a-base](../domains/a-base-system.md) §3.
|
||
- **Тир носителей `/data`:** **eMMC — прод/reference** (полные power-safe-гарантии); **SD —
|
||
dev/опционально** (power-safe деградирован: хуже при резком обрыве, нет прод-гарантий износа) — не для парка.
|
||
- Прямое следствие power-safe (принцип #5): запись только в `/data`.
|
||
|
||
## 3. Питание (критично) — power-safe by design
|
||
|
||
- **Управляемый power-path:** питание устройства коммутируется по зажиганию.
|
||
- **Детект ACC/зажигания** — через GPIO (12 В → level-shift).
|
||
- **Конверт входа (по ISO 7637-2 / 16750-2):** номинал ~9–16 В непрерывно; **cold-crank** —
|
||
детерминированная работа при просадке до ~6 В (не reset-петля); **under-voltage** — порог
|
||
brown-out + гистерезис → детерминированный graceful shutdown; **over-voltage / 24 В
|
||
jump-start** — выдержать норматив; **load-dump** — TVS-клипер (несупрессированные пики
|
||
сильно выше 40 В); широкодиапазонный DC-DC + reverse-polarity.
|
||
- **Hold-up энергия** для graceful shutdown при резком пропадании 12 В.
|
||
- **Secure boot** (verified boot RK3588) — **якорь доверия first-party** (из
|
||
[security-privacy.md](security-privacy.md): first-party = вшит в подписанный образ).
|
||
Подпись OTA — домен A.
|
||
|
||
🟡 **Выбор hold-up механизма:**
|
||
- **(рек.) MCU-копилот** — маленький always-on МК: мониторит зажигание, сигналит SoC
|
||
«выключайся» по ACC-off, держит watchdog, управляет power-sequencing и sleep/wake.
|
||
+ конденсатор/supercap на пару секунд для флаша и размонтирования.
|
||
- **(проще)** только supercap — буфер энергии без логики (детект ACC — на SoC-GPIO).
|
||
|
||
Рекомендую MCU-копилот: он же закрывает watchdog и пробуждение. (Прошивка МК — домен B.)
|
||
|
||
**Бюджет hold-up (числовой контракт; sizing — здесь, sequencing — домен B):** энергия =
|
||
worst-case ток (SoC + контроллер хранилища при флаше/unmount) × hold-time (верхняя оценка
|
||
flush+durable-write+unmount с запасом) × **дератинг** (низкая T −40 °C: ёмкость/ESR supercap
|
||
падают; старение). **Load-shedding:** при детекте power-loss сбрасываем тяжёлые потребители
|
||
(усилитель, подсветка, модем) → hold-up кормит ТОЛЬКО SoC+хранилище (power-path должен уметь
|
||
селективно держать SoC-рейл). **Латентный бюджет:** «детект → старт shutdown → последний
|
||
fsync». Различать резкий обрыв 12 В (hold-up + немедленный флаш) vs управляемый ACC-off.
|
||
|
||
**Детект ACC — кондиционированный сигнал, не голый уровень GPIO:** debounce/glitch-фильтр +
|
||
минимальная стабильная длительность ACC-off **больше** worst-case cold-crank-просадки;
|
||
гистерезис + **приоритет crank** (не инициировать shutdown, пока возможен запуск двигателя —
|
||
по восстановлению напряжения/RPM), иначе ложный shutdown→ребут на нормальном старте. Это
|
||
ответственность MCU-копилота (он эмитит дебаунснутый ACC + shutdown-imminent → ipc
|
||
`AccChanged`/`ShutdownImminent`); для supercap-only — то же в софте на SoC. → инвариант домена B.
|
||
|
||
**Требования к самому MCU-копилоту** (он критичен — watchdog/sequencing/shutdown): прошивка
|
||
**обновляема** (доступная линия/бутлоадер — баг в MCU не делает кирпич); **детерминированный
|
||
fail-safe при отказе/зависании самого MCU** (независимый аппаратный таймер снятия питания);
|
||
**позиция в цепочке доверия** — доверенный ли элемент secure boot, можно ли подменой его прошивки
|
||
обойти power/red-line-логику. Аппаратные требования — здесь; прошивка — домен B.
|
||
|
||
## 4. Периферия
|
||
|
||
| Узел | Старт | Прод / позже |
|
||
|------|-------|--------------|
|
||
| **Дисплей** | HDMI + USB-тачскрин | MIPI-DSI / LVDS панель |
|
||
| **CAN/OBD** | ELM327 (USB/BT) | нативный CAN-трансивер → **SocketCAN** |
|
||
| **GPS** | USB/UART, NMEA | **внешняя/активная антенна** (LNA); 1PPS — опц. (PPS-точность времени; на USB-донглах обычно нет) |
|
||
| **Связь** | USB-модем (ModemManager) / Wi-Fi | — |
|
||
| **Аудио** | I2S codec + усилитель (+ mute/enable-GPIO — anti-pop) | — |
|
||
| **Микрофон** | USB **mic-массив** (wake-word, шумоподавление) | — |
|
||
| **Радио** *(later)* | — | FM-тюнер (Si47xx-класс) — нужен для радио (домен H §7); 🟡 добавить или отказаться |
|
||
| **Камеры** | задняя (CVBS capture-чип + драйвер, **v2**) | dashcam / surround (задел, домен J) |
|
||
| **Мультируль** | кнопки руля: чтение с CAN **или** ADC (резистивная лесенка) | — |
|
||
|
||
**Два пути чтения и точный смысл «read-only»:**
|
||
- **Пассивный сниффинг (listen-only):** CAN-контроллер в silent-режиме — физически
|
||
не передаёт и не шлёт ACK; читаем broadcast-кадры машины (нужен DBC). Ноль TX.
|
||
- **OBD-II поллинг:** чтобы прочитать DTC и PID, протокол **требует отправить
|
||
кадр-запрос** (Mode 01/03/07/09). Это НЕ listen-only — мы передаём, но **только
|
||
стандартные диагностические read-запросы**.
|
||
|
||
**Red-line (принцип #2):** запрещены **управляющие/actuator-команды, запись в ECU,
|
||
сброс DTC (Mode 04), UDS-write** — любые *state-changing* передачи. Безобидные
|
||
read-запросы OBD-II разрешены (без них не прочитать ошибки). Чистый listen-only —
|
||
только для пассивного пути.
|
||
|
||
**ELM327 ≠ физическая гарантия:** ELM327 — полноценный CAN-узел (ACK-ит кадры, по AT-командам
|
||
может слать произвольные) → на ELM327-пути read-only = **software-дисциплина** (нет write-кода
|
||
в Vehicle-Data, нет write-метода/capability). **Физический** инвариант «ноль TX, писать некуда»
|
||
держится только на **нативном CAN в silent-режиме** (приходит с прод-путём, не на MVP). Поэтому
|
||
формулировки architecture §1 / security-privacy §1 про «физический факт» строго верны лишь для
|
||
нативного silent-CAN; на ELM327 скомпрометированный Vehicle-Data способен инжектить кадры.
|
||
ELM327 не убираем (E §3 — путь для старых не-CAN авто), но где нужна жёсткая гарантия — адаптер без TX.
|
||
|
||
**Задняя камера (контракт захвата; safety НЕ заявляем, принцип #1):** стандарт CVBS (PAL/NTSC) +
|
||
разрешение/fps; источник «задняя включена» — провод фонаря з.х. (GPIO, надёжнее/быстрее) vs CAN
|
||
gear-сигнал (тогда gear нужен в data-model); **латентность — инженерный бюджет** (#11:
|
||
time-to-first-frame + steady-state; verified boot добавляет Stage-0 задержку, мерить отдельно),
|
||
не регуляторное требование; **fail-safe:** при отказе чипа — явное «нет сигнала», не замёрзший
|
||
кадр (#4). Оверлей/UX — домен J.
|
||
|
||
**CAN front-end (электрика):** bus-fault-protected трансивер с расширенным common-mode;
|
||
корректное заземление/общий референс + обработка ground-offset; ESD/транзиент на CAN-H/L
|
||
(ISO 7637, шинная сторона — отдельно от §3); защита от backfeed через OBD-II pin 16 при любом
|
||
порядке включения. **Даже listen-only не должен электрически нагружать/искажать шину** (физ. бэкап #1).
|
||
|
||
## 5. HAL / board-support (портирование)
|
||
|
||
**HAL абстрагирует железо-специфичное**, чтобы платформа переносилась на другие
|
||
платы/авто:
|
||
|
||
- Power/зажигание (карта GPIO + протокол MCU-копилота).
|
||
- CAN (контроллер + listen-only).
|
||
- Дисплей (тип панели + тач), аудио (codec/усилитель/маршрутизация).
|
||
- GPS-источник, захват камер, карта ввода мультируля.
|
||
|
||
**BSP (board-support package)** = device tree (overlay) + конфиг HAL + **per-vehicle
|
||
DBC/маппинг сигналов** (см. [data-model.md](data-model.md) §7).
|
||
|
||
**Порт = новый BSP.** Это и есть «API под конкретное железо/авто» из vision:
|
||
автопроизводитель/энтузиаст поставляет BSP, ядро не трогается.
|
||
|
||
## 6. Первый таргет vs портируемость
|
||
|
||
- **Один reference-таргет доводим end-to-end** (vision: не «любое железо из коробки»).
|
||
Портируемость — силами других через BSP/HAL.
|
||
- 🟡 **Выбор конкретной платы — отложен** (решение по доступности/цене). Кандидаты:
|
||
Radxa Rock 5B / 5B+, Orange Pi 5 / 5 Plus, Khadas Edge2 — критерии: mainline-поддержка,
|
||
доступность (в т.ч. в РФ), цена, IO (CAN-способные пины), **температурный класс**, наличие **battery-RTC**.
|
||
|
||
---
|
||
|
||
## Открытые вопросы (→ роутинг)
|
||
|
||
- 🟡 **Выбор reference-платы** — procurement-решение (доступность/цена в РФ). → отдельно.
|
||
- ◻️ **Прошивка MCU-копилота** (детект ACC, sequencing, watchdog, протокол к SoC). → домен B.
|
||
- ◻️ **Ранний путь задней камеры** (Stage 0 boot) — аппаратная сторона. → домен J + B.
|
||
- 🟡 **Подписанные OTA** (вторая половина цепочки доверия; secure boot закрыт здесь). → домен A.
|
||
- 🟡 **Тепловой режим — софт закрыт** в [a-base](../domains/a-base-system.md) §10; **hardware-сторона открыта** (конверт/темп-класс/cold-start/охлаждение — §1a).
|
||
- ◻️ **Бюджет hold-up** (числа: ток/hold-time/дератинг) — выбор supercap/cap гейтится этим (§3).
|
||
- ◻️ **CAN-front-end части** (трансивер/защита) + **battery-RTC** на reference-плате — финализировать при выборе платы.
|
||
- 🟡 **FM-тюнер** (Si47xx-класс) для радио — добавить в периферию (§4) или отказаться от радио. → домен H §7.
|
||
- ◻️ **Amp mute/enable-GPIO** (anti-pop при boot/shutdown): линия + секвенс-контракт (mute-then-cut). → домен H §8 + B §4.
|
||
- ✅ **Износ eMMC/SD** → резолв в [a-base-system.md](../domains/a-base-system.md) §9–§10 (journald volatile, tmpfs, zram вместо swap, write-minimization).
|
||
|
||
---
|
||
|
||
## Журнал решений (hardware)
|
||
|
||
| Решение | Выбор | Дата |
|
||
|---------|-------|------|
|
||
| SoC | RK3588/RK3588S класс, 8–16 ГБ | 2026-06-16 |
|
||
| Хранилище | eMMC RO rootfs + журналируемый `/data` | 2026-06-16 |
|
||
| Hold-up питания | MCU-копилот + cap (🟡); supercap-only — проще | 2026-06-16 |
|
||
| CAN | пассивный listen-only + OBD read-запросы (без state-changing TX); ELM327 на старте | 2026-06-16 |
|
||
| Доверие | secure boot анкорит first-party; подпись OTA — домен A | 2026-06-16 |
|
||
| Портируемость | HAL + BSP; один reference-таргет first-party | 2026-06-16 |
|
||
| Конверт входа | ISO 7637-2/16750-2: 9–16В, cold-crank ~6В, jump-start 24В, load-dump TVS | 2026-06-16 |
|
||
| Hold-up | числовой бюджет (ток×hold×дератинг) + load-shedding; sizing — здесь, sequencing — B | 2026-06-16 |
|
||
| Тепло | конверт −20…+70 / −40…+85, темп-класс, cold-start, охлаждение (🟡); софт — A §10 | 2026-06-16 |
|
||
| ELM327 | read-only = software-дисциплина; физ. инвариант — только нативный silent-CAN | 2026-06-16 |
|
||
| Носители `/data` | eMMC прод (полный power-safe) / SD dev (деградировано) | 2026-06-16 |
|