14.1.1.3. Симуляторы#
Два значения TARGET собирают прошивку для запуска внутри симулятора на вашем хосте, без подключённого оборудования. Они существуют для того, чтобы прошивку можно было запускать и тестировать где угодно.
| Ядро | NPU | Симулятор |
|---|---|---|---|
| Cortex-M7 | None | QEMU |
| Cortex-M55 | Ethos-U55 (256 MACs) | Arm FVP – Corstone SSE-300 |
MPS2_AN500 – это базовая цель Cortex-M7 без NPU. Она работает под QEMU, который быстро запускается и является легковесным способом проверки платформонезависимого кода и набора тестов.
MPS3_AN547 – это Cortex-M55 с NPU Ethos-U55, запускаемый на Fast Models от Arm – FVP, который моделирует эталонную подсистему Corstone SSE-300. Это цель для проверки NPU и пути ML-моделей в симуляции.
Оба предоставляют файловую систему ROM и достаточно RAM (а на M55 – и NPU), так что скрипты машинного зрения и ML выполняются без изменений.
Реального датчика нет, но модуль csi всё равно работает с виртуальным – csi.CSI.snapshot() возвращает синтетический анимированный тестовый шаблон (прокручивающуюся шахматную доску в градациях серого, градиент в RGB565), а не живую сцену. Чтобы обработать реальное содержимое изображения, загрузите его из файла: image.Image из фикстуры в файловой системе ROM или поток image.ImageIO для записанных кадров.
14.1.1.3.1. Сборка и запуск#
Каждый симулятор – это хост-инструмент, который вы устанавливаете сами. Вы собираете цель как любую другую (см. Сборка прошивки), затем запускаете её командой run под соответствующим симулятором – run собирает образ ROMFS, загружает прошивку и оставляет её работающей с последовательным подключением, к которому можно подключиться.
14.1.1.3.1.1. MPS2_AN500 (QEMU)#
QEMU поставляется в большинстве пакетных менеджеров как системный эмулятор Arm:
Linux (Debian / Ubuntu) – установите его с помощью
apt:sudo apt install qemu-system-armmacOS – установите его с помощью Homebrew:
brew install qemu
Затем соберите и запустите цель:
make -j$(nproc) TARGET=MPS2_AN500
make TARGET=MPS2_AN500 run
14.1.1.3.1.2. MPS3_AN547 (Arm FVP)#
FVP – это Fixed Virtual Platform от Arm для Corstone SSE-300, поставляемая в составе Arm Virtual Hardware. Она доступна только для Linux – на Mac используйте вместо неё цель QEMU выше.
Скачайте бандл, распакуйте его и добавьте его каталог bin/ в ваш PATH:
wget https://artifacts.tools.arm.com/avh/11.31.28/avh-linux-x86_11.31_28_Linux64.tar.gz
mkdir -p ~/fvp
tar --strip-components=1 -xzf avh-linux-x86_11.31_28_Linux64.tar.gz -C ~/fvp
export PATH="$HOME/fvp/bin:$PATH"
FVP также нужны Python-библиотеки SDK в LD_LIBRARY_PATH во время работы. Экспортируйте его один раз на оболочку из корня репозитория – чтение SDK_VERSION сохраняет его корректным по мере того, как репозиторий обновляет закреплённый SDK:
export LD_LIBRARY_PATH="$HOME/openmv-sdk-$(cat SDK_VERSION)/python/lib:$LD_LIBRARY_PATH"
Затем соберите и запустите цель:
make -j$(nproc) TARGET=MPS3_AN547
make TARGET=MPS3_AN547 run
14.1.1.3.2. Запуск набора тестов#
Модульные тесты находятся в scripts/unittest/tests/, а их фикстуры-изображения и данные – в scripts/unittest/data/. Они запускаются с помощью mpremote, который монтирует scripts/unittest/ в работающий симулятор и выполняет его run.py.
Связь с симулятором медленна со стандартным mpremote, поэтому используйте копию, поставляемую в репозитории, с применённым патчем для последовательного порта (примените его один раз):
patch -N -p1 -d lib/micropython < tools/mpremote-qemu-serial.patch
Для MPS2_AN500 под QEMU запустите цель – она печатает псевдотерминал, на котором находится её последовательный порт (например, /dev/pts/5):
make TARGET=MPS2_AN500 run
Затем из другой оболочки направьте пропатченный mpremote на это устройство:
python3 lib/micropython/tools/mpremote/mpremote.py connect /dev/pts/5 \
mount scripts/unittest/ run scripts/unittest/run.py
Для MPS3_AN547 под FVP последовательным портом является telnet-сокет на порту 5555:
make TARGET=MPS3_AN547 run
python3 lib/micropython/tools/mpremote/mpremote.py connect socket://localhost:5555 \
mount scripts/unittest/ run scripts/unittest/run.py
run.py обнаруживает и выполняет каждый тест, печатая строку PASSED / FAILED для каждого теста с временем выполнения и сводкой в конце.
14.1.1.3.3. Добавление теста#
Тесты обнаруживаются автоматически. Чтобы добавить тест, поместите в scripts/unittest/tests/ файл, определяющий функцию unittest(data_path, temp_path), которая возвращает True, когда тест проходит, и False, когда он не проходит:
# scripts/unittest/tests/circles.py
def unittest(data_path, temp_path):
import image
img = image.Image(data_path + "/shapes.ppm", copy_to_fb=True)
circles = img.find_circles(threshold=5000, x_margin=30, y_margin=30, r_margin=30)
return len(circles) == 1 and circles[0][0:] == (118, 56, 22, 5856)
Аргументы data_path и temp_path указывают на две файловые системы, которые симулятор видит во время выполнения набора тестов:
Путь | Обеспечивается |
|---|---|
| Каталог хоста |
| Файловая система ROM платы только для чтения, встроенная в образ прошивки из |
Таким образом, новому тесту пересборка не нужна, а новой фикстуре – нужна: образ ROM привязан к romfs_config.json, а не к отдельным файлам данных, поэтому принудительно пересоберите его, обновив время доступа к romfs_config.json платы (или выполнив make TARGET=<TARGET> clean) и запустив снова.
Ожидаемые значения проверяются прямо в тесте, так что отдельного файла с ожидаемым выводом для поддержки нет. Чтобы пропустить тест во время выполнения – например, когда ему нужно оборудование, которое симулятор не моделирует – возбудите исключение, сообщение которого содержит "SKIPPED".