From 9be4a2aecc0f0c3e1cdb6ea86b317e11a9ff1399 Mon Sep 17 00:00:00 2001 From: Ezra Maccabee Date: Mon, 29 Jun 2026 14:06:05 +0300 Subject: [PATCH] # firmware_test: ready for TUI app --- CHANGELOG.md | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ docs/DEV_ARCH.md | 58 ++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 109 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e2587ea..ecb5683 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,66 @@ - Следить за развитием BSP: MQS, RGB, bootloader или `tft_app`. - Отслеживать локальные патчи поверх vendor SDK, которые нужно вести отдельным patch log. +## [2026-06-29] — Этапы 6г–7: MQS, HIL pytest firmware_test, Provisioning + +### Кратко + +- `firmware_test` получил MQS audio-тест, полный HIL pytest-стек для firmware_test + (opto + CAN через CDC) и команду `get_uid` для чтения OCOTP UID. +- Завершён Этап 6 целиком. Этап 7 (Provisioning draft) реализован. + +### Добавлено + +- `bsp/mqs/` + `bsp_mqs` — SAI3 + eDMA + MQS периферия, управление громкостью + через PWM4 SM0 + LM4875M. API: `bsp_mqs_init/deinit`, `bsp_mqs_play`, + `bsp_mqs_is_busy`, `bsp_mqs_amp_init/deinit`, `bsp_mqs_amp_set_volume`. +- `firmware/test/src/tests/test_mqs.c` — интерактивный тест: мелодия ~4 с + (A4 + E5, целочисленная LUT-синусоида), async-воспроизведение с USB keepalive, + `confirm_request("mqs_tone")` → PASS/FAIL оператором. +- `tools/hil/conftest.py` — класс `FirmwareCdcClient` и фикстура `firmware_cdc`: + подключение к firmware_test по USB CDC ACM, проверка живости через `ping→pong`. +- `tools/hil/06_test_firmware_opto.py` — HIL pytest для opto-теста через CDC: + автоматический оркестратор M5 реле → confirm, без участия оператора. +- `tools/hil/06_test_firmware_can.py` — HIL pytest для CAN-теста через CDC: + RX (M5→таргет) и TX (таргет→M5) направления независимо. +- `bsp/provisioning/` + `bsp_provisioning` — чтение OCOTP UID (8 байт) + через прямой доступ к `OCOTP->CFG0/CFG1` (паттерн `fsl_silicon_id_soc.c`). +- Команда `get_uid` в протоколе v2: `{"type":"cmd","cmd":"get_uid"}` → + `{"type":"uid_response","uid":"<16 hex символов>"}`. + +### Изменено + +- `protocol.h/c` — добавлена `protocol_send_uid_response()`. +- `cli.c` — добавлена ветка `strcmp(cmd_name, "get_uid")` в `handle_cmd()`; + исправлен порядок: `strstr` заменён на `strcmp` по аналогии с остальными командами. +- `bsp/README.md` — добавлены `bsp_mqs` и `bsp_provisioning` в таблицу и дерево. + +### Исправлено + +- MQS: отсутствие `.pwmchannelenable = true` в `pwm_signal_param_t` (NXP SDK ≥ 2.13) + приводило к тому что `PWM_SetupPwm()` не выставлял `OUTEN` → ШИМ не выходил на пин. + Маскировалось отладчиком (оставлял `OUTEN` от прошлой сессии), воспроизводилось + только при cold reset. +- OCOTP: `OCOTP_Init()` вызывал зависание при чтении UID (контроллер занят после + USB CDC init). Исправлено переходом на прямое чтение `OCOTP->CFG0/CFG1` + без инициализации контроллера — shadow registers доступны сразу после сброса. + +### Тесты + +- `06_test_firmware_opto.py` hardware-verified: тайминги `RELAY_ON_S=0.15`, + `RELAY_OFF_S=0.5`; финальное чтение через `bsp_opto_force_read()` обходит + race condition чётного числа ISR при дребезге реле. +- `06_test_firmware_can.py` hardware-verified: два направления (RX + TX), + `disableSelfReception=true` на таргете. +- `test_mqs` hardware-verified: async-воспроизведение + USB keepalive работает + корректно; blocking-вариант голодал USB за ~4 с. + +### Документация + +- `bsp/provisioning/README.md` — новый компонент: API, аппаратура, особенности + прямого чтения OCOTP. +- `PROTOCOL.md` — добавлена команда `get_uid` / событие `uid_response`. + ## [2026-06-23] — Buttons/display test modules и полный рефакторинг документации Диапазон: `22f98c311a4564d8f18ed72d11635bf908046b1e..` diff --git a/docs/DEV_ARCH.md b/docs/DEV_ARCH.md index 767b0db..26975b4 100644 --- a/docs/DEV_ARCH.md +++ b/docs/DEV_ARCH.md @@ -205,12 +205,10 @@ flowchart LR │ ├── 01_test_uart.py ← HIL тест bsp_uart_host (без M5) │ ├── 02_test_opto.py ← HIL тест bsp_opto (через M5StampPLC) │ ├── 03_test_can.py ← HIL тест bsp_can -│ ├── 04_test_button.py ← HIL тест bsp_button -│ ├── 05_test_usb_cdc.py ← HIL тест USB CDC +│ ├── 05_test_usb_cdc.py ← HIL тест USB CDC (bsp_usb_cdc, UART CLI) +│ ├── 06_test_firmware_opto.py ← HIL тест opto через firmware_test CDC +│ ├── 06_test_firmware_can.py ← HIL тест CAN через firmware_test CDC │ ├── m5/ -│ │ ├── agent.py ← MicroPython агент на M5StampPLC -│ │ ├── cli.py ← интерактивный CLI для ручного тестирования стенда -│ │ └── power.py ← управление питанием таргета из командной строки │ └── uv.lock │ ├── CMakePresets.json ← Debug · Release · host-debug · target-debug @@ -484,6 +482,30 @@ sequenceDiagram ML-->>PT: "ACTIVE" ``` +### Через firmware_test CDC — `06_test_firmware_*.py` + +Новый класс HIL-тестов: firmware_test прошит во Flash (не загружается pyOCD), +общение идёт по USB CDC ACM через `FirmwareCdcClient`. M5StampPLC управляет +сигналами, TUI/pytest оркестрирует `confirm_request` автоматически. + +```mermaid +sequenceDiagram + participant PT as pytest + participant M5 as M5StampPLC + participant FW as firmware_test (CDC) + + PT->>FW: run_selected(["opto"]) + FW-->>PT: test_begin + FW-->>PT: confirm_request("opto_in1_active") + PT->>M5: relay_set(RLY3, ON) + PT->>FW: confirm("opto_in1_active", true) + FW-->>PT: test_result(pass/fail) + FW-->>PT: summary +``` + +Фикстура `firmware_cdc` не ждёт `session_start` (одноразовое событие, может быть +пропущено при подключении) — проверяет живость через `ping → pong`. + Перед каждой тест-сессией фикстура `m5` автоматически включает питание таргета (RLY1), ждёт стабилизации, затем `loaded_` загружает ELF через pyOCD. ### Команды @@ -522,15 +544,33 @@ timeout-паттерн. ### 10.2 HIL target-тесты +Два класса HIL-тестов с разными транспортами: + +**Класс A — ELF-in-RAM (UART CLI):** pyOCD загружает прошивку в RAM, общение через +LPUART1 (MCU-Link VCOM). Тесты BSP-уровня, независимы от firmware_test. + ```bash Инструменты: pyOCD (SWD) + pyserial (UART) + pytest + M5StampPLC (реле) Пресет: target-debug → ram.ld → ITCM/DTCM -Запуск: just host::hil-run (на хосте) +Запуск: just host::hil-run ``` -Текущие тесты: `01_test_uart.py` (PING/ECHO/BUF_SIZE), `02_test_opto.py` -(оптовходы IN1/IN2/RS через M5), `03_test_can.py` (CAN-шина), `04_test_button.py` -(кнопочные входы), `05_test_usb_cdc.py` (USB CDC). +Тесты: `01_test_uart.py` (PING/ECHO/BUF_SIZE), `02_test_opto.py` +(оптовходы IN1/IN2/RS), `03_test_can.py` (CAN-шина), `04_test_button.py` +(кнопки), `05_test_usb_cdc.py` (USB CDC ACM). + +**Класс B — firmware_test во Flash (CDC):** firmware_test прошит штатно, +общение через USB CDC ACM (`FirmwareCdcClient`). M5StampPLC оркестрирует +`confirm_request` автоматически без участия оператора. + +```bash +Инструменты: pyserial (CDC) + pytest + M5StampPLC (реле) +firmware_test: прошит в Flash через USB SDP заранее +Запуск: just host::hil-firmware-opto / hil-firmware-can +``` + +Тесты: `06_test_firmware_opto.py` (opto IN1/IN2/RS, 6 шагов), +`06_test_firmware_can.py` (CAN RX + TX). ---