# Предлагаемые требования к будущей прошивке

Это проект требований по результатам реверса и проверки текущего C99-ядра. Он **не изменяет утверждённое ТЗ** и не является метрологическим/нормативным заключением. Код старого изделия — источник наблюдений, а коэффициенты и пороги нового должны соответствовать выбранным сенсорам и плате.

## Минимальное работоспособное ядро

| ID | Требование | Проверка готовности | Основание |
|---|---|---|---|
| M01 | Единый шаг ядра принимает значение, единицы/масштаб, тип источника, время и качество; каждый слот имеет отдельное состояние | Подать отсчёты двух каналов с разной частотой, убедиться в независимости состояния и свежести | Старое `0xAEC4`, нынешняя оркестрация в эмуляторе |
| M02 | Разрядность реального ADC не теряется между входом, калибровкой и журналом | Коды 65535, 65536, середина и верх выбранного 24-битного диапазона; signed/unipolar по контракту | В проекте u16-поля при 24-битном эмуляторе |
| M03 | Нет данных, прогрев, устаревшие данные, насыщение, отказ и невалидная калибровка — отдельные состояния, не обычный ноль | Пустая серия, обрыв потока, полная шкала, NaN/Inf на float-входе; отсутствие ложной «нормы» | Нынешний `mf`; старое ограничение диапазона |
| M04 | Фильтр работает непрерывно и видит только отсчёты/разрешённые аппаратные статусы, не истину генератора | Ступенька, одиночный выброс, серия выбросов, старт, пропуск, разные интервалы времени | Старые 4 слоя; метка `generated_outlier` в эмуляторе |
| M05 | Задано время реакции всего тракта и обнаружения опасного изменения | Измерить от подачи ступеньки до тревоги; проверять худший фазовый сдвиг сканирования | Количество фильтров без временной базы недостаточно |
| M06 | Экран предупреждения не останавливает обработку измерений и опасных тревог | Низкий заряд одновременно с газовым превышением; длинное меню/запись; контролируемая загрузка CPU | В старом режиме батареи 7 пропускается `0xAEC4` |
| C01 | Калибровка — реальное преобразование ADC/сигнала, с направлением и проверенной таблицей | Узлы, промежутки, границы, 0/1/MAX точек, дубли x, неверный порядок, переполнение | `0x9A7C`, `0xA9A4`; calibration.c пока пуст |
| C02 | Поведение вне таблицы явно выбрано: ошибка/ограничение/экстраполяция с признаком | Ниже нуля, выше span, отрицательный или невозможный результат | Старый код экстраполирует и затем ограничивает |
| C03 | Zero/span workflow использует устойчивый сигнал и откат до подтверждённого сохранения | Нестабильный газ, отмена, отключение датчика, плохой эталон, перезапуск до/во время записи | Старые меню и текущие/заводские поля |
| C04 | Калибровка имеет температуру, дату, идентификатор профиля сенсора и версию модели | Несовместимый профиль/версия не применяются молча | Старое поле температуры `+0x30`; выбранная новая плата |
| T01 | Температурная модель профиля имеет допустимый диапазон и политику отказа | Границы диапазона, отсутствие температуры, скачок и устаревание; непрерывность результата | Условия T/Tcal и полиномы старого прибора |
| T02 | Межгазовая коррекция не зависит от порядка обхода и не принимает верхнюю оценку влияния за точный коэффициент без решения | Перестановка каналов/правил; неизвестный или отключённый влияющий канал; отрицательный результат | Проверка cross_sensitivity.c; старая реализация пока не установлена |
| A01 | Пороговая схема — параметр типа канала: две верхние ступени либо допустимый интервал | `L-1`, `L`, `L+1`, `H-1`, `H`, `H+1`; все предшествующие состояния | Исходные ARM-тесты `0xC1F6` |
| A02 | Гистерезис/задержка/фиксация тревог заданы явно, со временем | Колебание вокруг порога, короткий всплеск, устойчивое превышение, снятие и новая высокая тревога | В старом фрагменте нет отдельного гистерезиса |
| A03 | Для тревог выбран документированный сигнал; оформление экрана не меняет его скрыто | Два разных входа в зоне «прилипания» экрана: проверить сохранение правильной тревожной семантики | Старое `203<x<=216→209` влияет на общий итог |
| A04 | Оповещение имеет приоритеты и правила подтверждения/отключения звука | Два одновременно активных канала, переход L→H и H→L, отказ, батарея, новое событие при mute | `0x1534`, общие flags и несколько видов выходов |
| S01 | Формат настроек/калибровок сериализован отдельно от C-структур | 32/64-битный хост, другой padding, повреждённые длина/версия/CRC; указатели не сохраняются | В текущих структурах есть pointers и size_t |
| S02 | Заводская и рабочая копии раздельны; сохранение атомарно и проверяет ошибки | Обрыв после каждого шага записи; отказ NVM; загрузка предыдущей валидной копии | Старые backup-поля, игнорируемые статусы |
| L01 | Журнал имеет sequence/head/count и определённую политику заполнения | Ёмкость−1/ёмкость/ёмкость+1; многократное кольцо; перезапуск и повреждённая запись | Старый счётчик обнуляется на 2000 |
| L02 | Все байты записи инициализированы; значение и качество однозначны | H после L другого канала, снятие тревоги, ошибочная запись и невозможное время | Старые поля H/L и неинициализированный +1 |
| U01 | Состояния прибора отделены от экранов: запуск, прогрев, работа, калибровка, заряд, выключение, отказ | Переходы и отмены, таймаут, перезапуск; доступность тревог в каждом режиме | Старое gating по состоянию `>=10` |
| U02 | Самотест различает команду выходу и подтверждение исправности | Отключённый свет/звук/вибрация; если обратной связи нет, не сообщать доказанную исправность | Startup реально включает выходы, но feedback не подтверждён |
| U03 | Опасные сервисные операции явно подтверждаются и журналируются | Отмена не меняет память; восстановление отличается от перезаписи заводской копии | Меню B5/B6 старого бинарника |

## Порядок реализации

1. **Контракт измерения + тестовый стенд:** M01–M04, конечность чисел, независимые каналы. Генератор и проверяющий эталон отделить от алгоритма. Подключить выполняемые тесты к сборке/CI.
2. **Калибровка:** C01–C04, затем температурные профили. Модель старого прибора использовать для сравнительных тестов, но не для подстановки неподтверждённых коэффициентов.
3. **Тревоги:** A01–A04 вместе с качеством данных и временем реакции M05. Утвердить граничную семантику и поведение во время меню/калибровки.
4. **Хранилище и журнал:** S01–S02, L01–L02 сначала на файловом адаптере с внедрением отказов; затем физический драйвер.
5. **Аппаратные адаптеры и интерфейс:** U01–U03, реальный ADC/цифровые сенсоры, температура, питание, часы, оповещатели. Измерения на собственном железе обязательны.

Не требуется воспроизводить внутренний 57-байтный формат, расположение EEPROM, номера GPIO, пороги или эмпирические «подгонки» старого прибора. Требуется понимать их назначение и иметь проверяемую собственную реализацию.
