Комментарии 2
А можно чуть подробнее про то как происходило тестирование в Unicorn? Загрузка с нуля? Как быть с отсутствующей периферией? Выполнение кода из середины? Как воссоздать актуальное состояние?
Да. Unicorn использовался не как «виртуальный STM32 целиком», а как CPU-level стенд для конкретных путей исполнения.
Было два режима:
отдельно прогонялся startup-код, чтобы получить правдоподобное runtime-состояние RAM после инициализации;
основное тестирование шло с запуском из середины прошивки: выставлялись реальные значения RAM/регистров, PC ставился на нужную функцию, и дальше исполнялись настоящие Thumb-инструкции.
Периферия полностью не эмулировалась. На аппаратно-зависимых вызовах ставились hooks/stubs: они фиксировали, какая штатная функция была вызвана и с какими аргументами, после чего возвращали ожидаемый статус. То есть проверялось не «щёлкнулось ли физическое реле», а что прошивка дошла до правильного аппаратного вызова через правильный программный путь.
Для сценариев переключения входов в RAM воссоздавались конкретные состояния: текущий source, requested source, stage/timer автомата, UI/NVRAM-related значения. Затем подавалась команда и проверялось, как ведёт себя штатный worker, в том числе при повторных и незавершённых переключениях.
В Unicorn проверялись:
branch target после патча;
корректность Thumb-кода;
stack alignment и сохранение регистров;
запись правильного source ID;
вызов штатного request/worker;
изменения RAM;
repeated/interrupted transitions;
routing image и NVRAM-логика.
А вот реальные IRQ timing, GPIO/I²C/CEC, аналоговые переходы, updater и recovery Unicorn не подтверждал. Это уже проверялось только на живом QUAD.
То есть идея была не в том, чтобы «эмулировать усилитель», а в том, чтобы достаточно реалистично проверить именно тот программный путь, который меняет бинарный патч.

Как я добавил в QUAD 3 прямой выбор входов: реверс ARM-прошивки, бинарный патч и 64 байта здравого смысла