# firmware_test: ready for TUI app

This commit is contained in:
Dmitry Akimov 2026-06-29 14:06:05 +03:00
parent 3aa8974def
commit 9be4a2aecc
2 changed files with 109 additions and 9 deletions

View file

@ -58,6 +58,66 @@
- Следить за развитием BSP: MQS, RGB, bootloader или `tft_app`. - Следить за развитием BSP: MQS, RGB, bootloader или `tft_app`.
- Отслеживать локальные патчи поверх vendor SDK, которые нужно вести отдельным patch log. - Отслеживать локальные патчи поверх 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 и полный рефакторинг документации ## [2026-06-23] — Buttons/display test modules и полный рефакторинг документации
Диапазон: `22f98c311a4564d8f18ed72d11635bf908046b1e..<NEW_SHA>` Диапазон: `22f98c311a4564d8f18ed72d11635bf908046b1e..<NEW_SHA>`

View file

@ -205,12 +205,10 @@ flowchart LR
│ ├── 01_test_uart.py ← HIL тест bsp_uart_host (без M5) │ ├── 01_test_uart.py ← HIL тест bsp_uart_host (без M5)
│ ├── 02_test_opto.py ← HIL тест bsp_opto (через M5StampPLC) │ ├── 02_test_opto.py ← HIL тест bsp_opto (через M5StampPLC)
│ ├── 03_test_can.py ← HIL тест bsp_can │ ├── 03_test_can.py ← HIL тест bsp_can
│ ├── 04_test_button.py ← HIL тест bsp_button │ ├── 05_test_usb_cdc.py ← HIL тест USB CDC (bsp_usb_cdc, UART CLI)
│ ├── 05_test_usb_cdc.py ← HIL тест USB CDC │ ├── 06_test_firmware_opto.py ← HIL тест opto через firmware_test CDC
│ ├── 06_test_firmware_can.py ← HIL тест CAN через firmware_test CDC
│ ├── m5/ │ ├── m5/
│ │ ├── agent.py ← MicroPython агент на M5StampPLC
│ │ ├── cli.py ← интерактивный CLI для ручного тестирования стенда
│ │ └── power.py ← управление питанием таргета из командной строки
│ └── uv.lock │ └── uv.lock
├── CMakePresets.json ← Debug · Release · host-debug · target-debug ├── CMakePresets.json ← Debug · Release · host-debug · target-debug
@ -484,6 +482,30 @@ sequenceDiagram
ML-->>PT: "ACTIVE" 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_<n>` загружает ELF через pyOCD. Перед каждой тест-сессией фикстура `m5` автоматически включает питание таргета (RLY1), ждёт стабилизации, затем `loaded_<n>` загружает ELF через pyOCD.
### Команды ### Команды
@ -522,15 +544,33 @@ timeout-паттерн.
### 10.2 HIL target-тесты ### 10.2 HIL target-тесты
Два класса HIL-тестов с разными транспортами:
**Класс A — ELF-in-RAM (UART CLI):** pyOCD загружает прошивку в RAM, общение через
LPUART1 (MCU-Link VCOM). Тесты BSP-уровня, независимы от firmware_test.
```bash ```bash
Инструменты: pyOCD (SWD) + pyserial (UART) + pytest + M5StampPLC (реле) Инструменты: pyOCD (SWD) + pyserial (UART) + pytest + M5StampPLC (реле)
Пресет: target-debug → ram.ld → ITCM/DTCM Пресет: 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` Тесты: `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` (оптовходы IN1/IN2/RS), `03_test_can.py` (CAN-шина), `04_test_button.py`
(кнопочные входы), `05_test_usb_cdc.py` (USB CDC). (кнопки), `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).
--- ---