Что уже есть в будущем ядре и что нужно уточнить по старому прибору
Проверка исходников: 2026-09-13, коммит 4bb7cda8dee7109531a9cdf089e604c8a0175447.
Этот файл сравнивает текущий C99-проект с потребностями будущей прошивки. Реализация старого прибора здесь не объявляется установленной: пересказы предыдущего чата служат указателями для проверки бинарника. Отсутствие модуля в нашем проекте ничего не говорит о наличии такого модуля в старом приборе.
Проверены src/, include/, tests/, scenarios/, CMakeLists.txt, .gitlab-ci.yml, README.md и три контекстных документа из E:\. Инструкции внутри перенесённых документов рассматриваются как история, а не как команды на изменение или коммит. Исходники ядра не изменялись.
Основные пробелы
| Область | Что действительно реализовано | Чего ещё нет / что проверить | Указатель в исходниках |
| Путь измерения | Температурная поправка → перекрёстная коррекция → пороговые тревоги | Единый вызываемый цикл ядра с реальным входом, временем и результатом; сейчас оркестрация является static-функцией внутри интерактивного эмулятора | src/emulator.c:361 |
| АЦП и представление данных | Условный беззнаковый 24-битный код в uint32_t, перевод через условные 3,3 В | CalibrationPoint.raw_adc и GasChannelState.raw_adc имеют лишь 16 бит. Они не вмещают объявленный 24-битный диапазон; raw_adc сейчас вообще записывается как ноль. Нет контракта полярности, опоры, усиления, статуса и времени отсчёта | include/gas_types.h:31, include/gas_types.h:97, src/emulator.c:254, src/emulator.c:327 |
| Калибровка | Таблица до пяти точек как структура | Интерполяция, проверка таблицы, процедуры zero/span, стабильность отсчётов, сохранение результата, откат/отмена, метаданные датчика и даты отсутствуют. calibration_init() — заглушка, все point_count = 0 | src/calibration.c:3, src/emulator.c:53 |
| Фильтр | Кольцевой буфер, сумма uint64_t, окна 8/16/32; при неполном окне среднее по фактическому числу отсчётов | Окна 4 из первого ТЗ нет; постоянного состояния фильтров по каналам, периода выборки и отдельных значений для индикации/тревоги нет. В mf фильтр создаётся заново для каждой серии | src/filter.c:10, include/filter.h:9, src/emulator.c:714 |
| Температура | Линейная интерполяция по статическим приблизительным таблицам O₂/CO/H₂S; крайняя точка за границей таблицы | Режимы OFF/TABLE/POLYNOMIAL из ТЗ, индивидуальные коэффициенты, источник и свежесть температуры, статус отказа. Для H₂S в поле «процент сигнала при 20 °C» записано 98 при 20 °C: нужно проверить точку нормировки. CO₂-таблицы нет | src/temperature_compensation.c:21, src/temperature_compensation.c:62, src/temperature_compensation.c:123 |
| Перекрёстное влияние | Четыре статических правила, последовательное вычитание, специальная ветка CO₂ → O₂ | is_upper_bound не меняет вычисление; верхняя граница влияния применяется как точный коэффициент. Единицы правил не валидируются. Источники изменяются на месте, поэтому при взаимных ненулевых связях возможна зависимость от порядка правил. Нет учёта невалидного/отключённого влияющего канала | src/cross_sensitivity.c:3, src/cross_sensitivity.c:34, src/cross_sensitivity.c:65, include/gas_types.h:55 |
| Тревоги | LOW для O₂, HIGH для всех, SENSOR_FAULT имеет приоритет; общий флаг тревоги | Нет гистерезиса, задержек, фиксации/подтверждения, уровней превышения, переходов состояний и управления исполнительными узлами. Флаг enabled не учитывается. На точном равенстве порогу тревоги нет из-за </> — желаемую семантику нужно задать и проверить | src/alarms.c:8, src/alarms.c:18, src/alarms.c:29 |
| Качество измерения | Булевый sensor_fault в структуре | Нет статусов «прогрев», «нет данных», «данные устарели», «вне диапазона», «калибровка неверна». Все три команды измерения сбрасывают sensor_fault = false; аппаратных причин отказа никто не устанавливает | include/gas_types.h:108, src/emulator.c:317, src/emulator.c:338, src/emulator.c:358 |
| Журнал | Только event_log_init() | Структура записи, timestamp, кольцевой архив, запись начала/окончания тревог и ошибок, восстановление после сбоя, выгрузка | src/event_log.c:3 |
| Настройки и память | Только settings_init() / storage_init() | Версия формата, проверка целостности, атомарное сохранение, заводские данные, разделение заводской/пользовательской калибровки, интерфейс хранилища, файловая модель для ПК | src/settings.c:3, src/storage.c:3 |
| Интерфейс, питание, обслуживание | Консольные команды, показ значений/диагностики | Автомат экранов, кнопки и удержания, батарея/зарядка/выключение, часы, звуковые/световые/вибрационные шаблоны, сервисная калибровка, формат обмена и обновление | src/main.c:39, src/emulator.c:808 |
| Проверки | CMake собирает один исполняемый файл; CI собирает Windows-версию | Все четыре test_*.c содержат только комментарий. Нет CTest и CI-тестов. CSV-файлы — шаблонные строки с нулевыми данными, чтения сценариев нет | CMakeLists.txt:9, tests/, scenarios/, .gitlab-ci.yml |
Почему демонстрация может давать ложную уверенность
mпринимает уже готовые ppm/% и затем меняет их поправками. Если пользователь считает введённые числа окончательной концентрацией, результат будет отличаться от ожидаемого: симулятор не добавляет температурное/перекрёстное искажение к сигналу перед последующим его устранением. Это проверка выбранного вычислительного пути, а не точности прибора (src/emulator.c:300,src/emulator.c:581).
mvне выполняет полный круг через АЦП. Значениеcalibrated_valueрассчитывается прямо из введённого напряжения; отдельно для диагностики получаетсяadc_code. Пересчёт обратно из кода АЦП на результатmvне влияет (src/emulator.c:341). Строка «Калибровка» на экране пока обозначает условную линейную шкалу 0,2–2,8 В, а не индивидуальную калибровку.
mfзнает, какой отсчёт был искусственным выбросом. Условиеgenerated_outlier || is_outlier_voltage(base_voltage_v, sample_voltage_v)использует метку генератора и заранее известное истинное напряжение (src/emulator.c:730). У реального прибора таких входов нет. Для исследования алгоритма отбраковки генератор должен передавать только отсчёты и разрешённые аппаратные статусы; эталон нужен отдельной проверяющей стороне.
- Пустая/неполная серия превращается в обычное измерение. После исчерпания попыток
mfберёт среднее даже при нуле принятых отсчётов, когдаfilter_get_average()возвращает ноль, и сохраняет канал сsensor_fault = false(src/filter.c:48,src/emulator.c:745). При неполном окне печатается предупреждение, но качество результата не попадает в состояние устройства.
- Ограничение диапазона скрывает исходную причину.
voltage_to_gas()превращает любой вход ниже минимума в ноль, выше максимума — в верх диапазона (src/emulator.c:228). Значение перегрузки или обрыва после этого нельзя отличить от соответствующей концентрации без отдельного статуса. Это актуально и при чтении старой прошивки: искать нужно обработку качества вместе с числом.
NaNне отсекается.strtof()допускает такой ввод, проверки диапазона его не отбрасывают, а сравнения с порогами сами по себе не переводятNaNв SENSOR_FAULT. Затем код эмулятора пытается преобразовать нечисловой float вuint32_t(src/emulator.c:130,src/emulator.c:266,src/alarms.c:18). Требуется явная проверка конечности входов и выходов. Это вывод из кода, не результат исполнения.
- Сохранение C-структуры целиком не является форматом памяти. В
GasChannelConfigесть указатели на строки, а в таблицах —size_t. Их нельзя переносимо записать в файл/Flash как есть: размер, выравнивание и значения указателей зависят от платформы. Нужна отдельная сериализация с определёнными разрядностью и порядком байтов.
Что вынести из старого бинарника в требования
| Что искать в старом приборе | Какое решение для будущего ядра это поможет обосновать |
| Инициализацию АЦП, порядок каналов, частоту вызовов, представление результата | Контракт входного отсчёта, постоянное состояние каналов, время реакции; электрические коэффициенты всё равно должны соответствовать новой плате |
| Буфер усреднения, поведение при старте и насыщении | Фильтры и проверки ступеньки/импульса/обрыва; сам размер окна без частоты измерения недостаточен |
| Чтение и изменение zero/span/таблиц, проверку допустимости калибровки | Проверяемую модель калибровки и процедуру её проведения, а не копирование чужих коэффициентов |
| Ссылки на параметры температуры и реальные вызовы корректирующей функции | Рабочий путь температуры. Одна математическая функция или слово в меню не доказывает, что компенсация используется |
| Чтение настроек, заводское восстановление, области журнала | Схему хранения, отказоустойчивость и разделение заводских/пользовательских данных. Основной BIN может не содержать действующие калибровки внешней памяти |
| Сравнения порогов, таймеры, флаги подтверждения и вызовы сигнализации | Автомат тревог и событий, включая ситуацию нескольких одновременно активных каналов |
| Включение/выключение, проверку батареи, ошибки, кнопки, экраны и сервисные команды | Состояния всего прибора и требования к аппаратным адаптерам |
Адресные зацепки из E:\Вставленный текст.txt: 0x9DD8 и 0xA134 — предполагавшаяся табличная калибровка, 0xA6AC — предполагаемый полином, 0x1360 — предполагаемая запись журнала, 0xECF0/0xEF74 — предполагаемые чтение/запись EEPROM, состояния 0xB4/0xB5/0xB6 — предполагаемые заводские меню. Это не результаты независимой проверки данного отчёта. Для каждого адреса нужны код функции, её вызывающие функции, данные и условия использования.
Контекстные документы противоречат друг другу по CO₂: первый закреплял аналоговый химический канал, второй прямо оставляет модель и интерфейс открытыми. Фактически в проекте стоит TEMP_CO2_ANALOG. Поэтому интерфейс четвёртого канала остаётся временным; BIN другого прибора не определяет выбор датчика будущей модели.
Практический порядок последующей реализации
- Определить вход/выход одного шага ядра: код или готовая концентрация, тип источника, единицы, время, качество; привести разрядность полей АЦП к согласованной модели. Отделить генератор отсчётов и консоль от обработки.
- Сделать реальную калибровку с проверкой точек и явно выбранным поведением за границами. Состояние «нет корректной калибровки» должно быть представимо отдельно от числа.
- Подключить постоянные фильтры каналов и отслеживание свежести; проверить старт, отсутствие данных, ступеньку, выброс и насыщение на детерминированных последовательностях.
- Описать автомат тревог с переходами, временем и качеством измерений; события передавать журналу и индикации через отдельные интерфейсы.
- Реализовать сериализацию настроек/калибровок и журнал с имитацией прерванной записи, повреждения, заполнения и восстановления на ПК.
- Добавить состояния запуска, прогрева, калибровки, работы, зарядки и выключения; реальные драйверы подключать через адаптеры после фиксации платы.
Минимальные предметные проверки: АЦП выше 65535 без потери старших битов; таблицы из 0/1/5 точек, повторы и обратный порядок; нечисловые значения; пустой и частично заполненный фильтр; отключённый канал; устаревший температурный канал; точное равенство порогу и колебания около него; две одновременные тревоги; взаимная коррекция при перестановке правил; прерванная запись калибровки; повреждённая версия/контрольная сумма; заполненный журнал.
Сборка и исполнение тестов в этой проверке не выполнялись: gcc, clang и cmake не обнаружены в доступном PATH Windows и WSL Debian. Новые инструменты не устанавливались. Выводы о поведении основаны на статическом просмотре исходников.