# 1. Набросок архитектуры firmware_test
This commit is contained in:
parent
310a8d6bc9
commit
806b41e0a5
4 changed files with 513 additions and 3 deletions
|
|
@ -167,5 +167,3 @@ just flash # прошивка через USB ROM
|
||||||
|
|
||||||
> Подробнее о прошивке — [HOW_TO_FLASH.md](HOW_TO_FLASH.md)
|
> Подробнее о прошивке — [HOW_TO_FLASH.md](HOW_TO_FLASH.md)
|
||||||
> Подробнее об окружении разработки — [docs/DEV_ARCH.md](docs/DEV_ARCH.md)
|
> Подробнее об окружении разработки — [docs/DEV_ARCH.md](docs/DEV_ARCH.md)
|
||||||
>
|
|
||||||
>
|
|
||||||
|
|
@ -34,7 +34,7 @@ CI использует те же команды что и локальная р
|
||||||
│ ├── docker ← управление devcontainer
|
│ ├── docker ← управление devcontainer
|
||||||
│ ├── git ← работа с репозиторием
|
│ ├── git ← работа с репозиторием
|
||||||
│ ├── uv + spsdk ← прошивка платы (flash_usb.py, sdphost, blhost)
|
│ ├── uv + spsdk ← прошивка платы (flash_usb.py, sdphost, blhost)
|
||||||
│ │ venv: tools/host/.venv-host (Linux/macOS)
|
│ │ venv: tools/host/.venv. (Linux/macOS)
|
||||||
│ │ tools/host/.venv-host-win (Windows)
|
│ │ tools/host/.venv-host-win (Windows)
|
||||||
│ ├── JLinkGDBServer / probe-rs ← сервер отладки (USB → TCP :2331)
|
│ ├── JLinkGDBServer / probe-rs ← сервер отладки (USB → TCP :2331)
|
||||||
│ └── VSCode ← IDE (Dev Containers extension)
|
│ └── VSCode ← IDE (Dev Containers extension)
|
||||||
|
|
|
||||||
244
firmware/test/README.md
Normal file
244
firmware/test/README.md
Normal file
|
|
@ -0,0 +1,244 @@
|
||||||
|
# firmware_test — Architecture
|
||||||
|
|
||||||
|
> Target: NXP IMXRT1052CVJ5B
|
||||||
|
> Версия документа: 0.1
|
||||||
|
> Статус: draft
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Назначение
|
||||||
|
|
||||||
|
`firmware_test` — входная тестовая прошивка для проверки работоспособности платы при производстве и во время разработки. Запускается напрямую через BootROM (USB Serial Download), без предварительной прошивки загрузчика. После успешного прохождения всех тестов инициирует фазу провижининга (привязка Chip UID к версиям ПО).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Workflow прошивки платы
|
||||||
|
|
||||||
|
```bash
|
||||||
|
BootROM (USB Serial Download, встроен в IMXRT1052)
|
||||||
|
↓
|
||||||
|
firmware_test (залит напрямую)
|
||||||
|
↓ [тесты прошли, provisioning выполнен]
|
||||||
|
Флашим: Bootloader + App
|
||||||
|
↓
|
||||||
|
Ждём heartbeat Bootloader → App
|
||||||
|
↓
|
||||||
|
Плата принята
|
||||||
|
```
|
||||||
|
|
||||||
|
Вариант с предварительной заливкой загрузчика не используется — BootROM является надёжным и всегда доступным recovery-path, не зависящим от состояния Flash.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Высокоуровневая архитектура
|
||||||
|
|
||||||
|
```bash
|
||||||
|
┌─────────────────────────────────────────────────────┐
|
||||||
|
│ firmware_test │
|
||||||
|
│ │
|
||||||
|
│ USB CDC ──► Protocol ──► Test runner ──► Local UI │
|
||||||
|
│ (JSON-lines) (sequencer) (LED+disp) │
|
||||||
|
│ │
|
||||||
|
│ ┌─────────────────────┐ ┌──────────────────────┐ │
|
||||||
|
│ │ self-tests │ │ HIL tests │ │
|
||||||
|
│ │ SDRAM QSPI uSD │ │ CAN UART Opto-in │ │
|
||||||
|
│ │ RTC Display IR │ │ UART ISO IR burst │ │
|
||||||
|
│ └─────────────────────┘ └──────────────────────┘ │
|
||||||
|
│ │
|
||||||
|
│ HAL / BSP │
|
||||||
|
└─────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Компоненты
|
||||||
|
|
||||||
|
### 4.1 USB CDC
|
||||||
|
|
||||||
|
Единственный канал связи с внешним миром. Представляется хосту как виртуальный COM-порт. Инициализируется первым, до запуска тестов. При старте ожидает подключения хоста с таймаутом — если хост не подключился, тесты запускаются автономно.
|
||||||
|
|
||||||
|
### 4.2 Protocol
|
||||||
|
|
||||||
|
Протокол — **JSON-lines**: каждое сообщение является отдельным JSON-объектом, завершённым символом `\n`. Библиотека: cJSON из NXP SDK.
|
||||||
|
|
||||||
|
Направление **хост → плата** (команды):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"type":"cmd","cmd":"run_all"}
|
||||||
|
{"type":"cmd","cmd":"run","id":"sdram"}
|
||||||
|
{"type":"confirm","id":"display","confirmed":true}
|
||||||
|
```
|
||||||
|
|
||||||
|
Направление **плата → хост** (события):
|
||||||
|
|
||||||
|
```json
|
||||||
|
{"type":"session_start","fw":"0.1.0","target":"IMXRT1052","uptime_ms":0}
|
||||||
|
{"type":"test_begin","id":"sdram","name":"SDRAM 32MB","critical":true}
|
||||||
|
{"type":"test_result","id":"sdram","status":"pass","ms":312,"detail":"32MB R/W OK"}
|
||||||
|
{"type":"confirm_request","id":"display","timeout_ms":15000}
|
||||||
|
{"type":"abort","reason":"critical_fail","id":"usd"}
|
||||||
|
{"type":"summary","passed":7,"failed":0,"skipped":2,"aborted":false,"overall":"pass"}
|
||||||
|
{"type":"provision_ready","chip_uid":"A3F2C1B400E70012"}
|
||||||
|
{"type":"provision_ack","fw":"1.0.0","bootloader":"1.0.0","recorded":true}
|
||||||
|
```
|
||||||
|
|
||||||
|
> **Примечание:** `uptime_ms` вместо Unix timestamp — RTC может быть не инициализирован на новой плате. Хост приклеивает реальное время самостоятельно.
|
||||||
|
|
||||||
|
### 4.3 Test runner
|
||||||
|
|
||||||
|
Центральный компонент. Хранит реестр тест-модулей, управляет порядком запуска, обрабатывает критические сбои, формирует `summary`.
|
||||||
|
|
||||||
|
**Порядок выполнения:**
|
||||||
|
|
||||||
|
1. Self-tests в порядке реестра
|
||||||
|
2. Проверка критических сбоев — если есть, HIL не запускается
|
||||||
|
3. HIL tests (только если Firefly подключён и self-tests прошли)
|
||||||
|
4. Summary report
|
||||||
|
5. Provisioning (только при `overall == pass`)
|
||||||
|
|
||||||
|
**Интерфейс тест-модуля (`test_module.h`):**
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
typedef enum {
|
||||||
|
TEST_STATUS_PASS = 0,
|
||||||
|
TEST_STATUS_FAIL,
|
||||||
|
TEST_STATUS_SKIP,
|
||||||
|
} test_status_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
test_status_t status;
|
||||||
|
uint32_t duration_ms;
|
||||||
|
char detail[96]; /* диагностическая строка, опционально */
|
||||||
|
} test_result_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *id; /* "sdram", "qspi", "can" — ключ в JSON */
|
||||||
|
const char *name; /* "SDRAM 32MB" — для display/лога */
|
||||||
|
bool critical; /* abort HIL если FAIL */
|
||||||
|
bool requires_hil; /* пропустить если Firefly не готов */
|
||||||
|
void (*init)(void);
|
||||||
|
test_result_t (*run)(void);
|
||||||
|
void (*deinit)(void);
|
||||||
|
} test_module_t;
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.4 Local UI
|
||||||
|
|
||||||
|
Отображает текущее состояние тестирования на светодиодах и дисплее. Получает события от Test runner. Дисплей при этом является частью тест-процесса (display_test).
|
||||||
|
|
||||||
|
**LED-паттерны:**
|
||||||
|
|
||||||
|
| Состояние | LED1 | LED2 |
|
||||||
|
|------------------------|-------------|-------------|
|
||||||
|
| Тест выполняется | мигает | выкл |
|
||||||
|
| Все тесты PASS | вкл | выкл |
|
||||||
|
| Есть FAIL | выкл | вкл |
|
||||||
|
| Ожидание подтверждения | оба мигают | |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Тест-модули
|
||||||
|
|
||||||
|
### 5.1 Self-tests
|
||||||
|
|
||||||
|
| ID | Название | Critical | Описание |
|
||||||
|
|------------|------------------|----------|--------------------------------------------------|
|
||||||
|
| `sdram` | SDRAM 32MB | ✅ | Write/read паттерны по всему объёму |
|
||||||
|
| `qspi` | QSPI Flash | ✅ | JEDEC ID + запись/чтение тестового сектора |
|
||||||
|
| `usd` | uSD (SDIO) | ✅ | Mount + R/W тестового файла (SKIP если нет карты)|
|
||||||
|
| `rtc` | RTC BM8563 | — | I2C presence, set/get time |
|
||||||
|
| `display` | Display RGB888 | — | R/G/B/W заливки, подтверждение оператором |
|
||||||
|
| `ir` | IR receiver | — | GPIO idle state HIGH, peripheral init |
|
||||||
|
|
||||||
|
**Display test — логика подтверждения:**
|
||||||
|
|
||||||
|
- Плата посылает `confirm_request` с `timeout_ms: 15000`
|
||||||
|
- Оператор нажимает **одну** кнопку: PASS или FAIL
|
||||||
|
- Если кнопка не нажата за 15 секунд — статус `SKIP` (ответственность на операторе)
|
||||||
|
- Одновременно проверяются обе кнопки — это полноценный тест кнопок
|
||||||
|
|
||||||
|
### 5.2 HIL tests (требуют Firefly AIO-3588Q)
|
||||||
|
|
||||||
|
| ID | Название | Стенд | Описание |
|
||||||
|
|--------------|------------------|------------------------------|----------------------------------------|
|
||||||
|
| `can` | CAN | Firefly CAN | Обмен фреймами, full-duplex |
|
||||||
|
| `uart_ttl` | UART TTL | Firefly UART | Echo паттерн |
|
||||||
|
| `uart_iso` | UART ISO +24V | Firefly UART + интерф. плата | Только RX, Firefly посылает |
|
||||||
|
| `opto` | Opto-in +24V | Firefly GPIO + интерф. плата | Все каналы, Firefly дёргает GPIO |
|
||||||
|
| `ir_hil` | IR burst | Firefly GPIO + IR LED | Приём burst 38 кГц, факт прерывания |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Provisioning
|
||||||
|
|
||||||
|
Выполняется после `summary: overall == pass`. Не является тестом — это отдельный этап жизненного цикла платы.
|
||||||
|
|
||||||
|
**Источник UID:** регистры OCOTP (One-Time Programmable fuses), 64-bit Chip UID. Читается через HAL.
|
||||||
|
|
||||||
|
**Интерфейс (`provisioning.h`):**
|
||||||
|
|
||||||
|
```c
|
||||||
|
typedef struct {
|
||||||
|
char chip_uid[17]; /* 64-bit UID как hex-строка, null-terminated */
|
||||||
|
char fw_version[16];
|
||||||
|
char bootloader_version[16];
|
||||||
|
bool provisioned;
|
||||||
|
} provision_info_t;
|
||||||
|
|
||||||
|
/* вызывается только при overall == PASS */
|
||||||
|
void provisioning_run(provision_info_t *out);
|
||||||
|
```
|
||||||
|
|
||||||
|
**Поток:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
плата посылает provision_ready + chip_uid
|
||||||
|
↓
|
||||||
|
хост записывает в БД: uid ↔ fw_version ↔ bootloader_version
|
||||||
|
↓
|
||||||
|
хост посылает provision_ack
|
||||||
|
↓
|
||||||
|
плата устанавливает provisioned = true
|
||||||
|
```
|
||||||
|
|
||||||
|
Вся логика на стороне хоста (запись в БД, генерация сертификата, привязка партии). Прошивка только читает UID и ждёт подтверждения.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Реестр тестов
|
||||||
|
|
||||||
|
```c
|
||||||
|
/* test_registry.c */
|
||||||
|
static const test_module_t *tests[] = {
|
||||||
|
&test_sdram, /* critical */
|
||||||
|
&test_qspi, /* critical */
|
||||||
|
&test_usd, /* critical, SKIP если нет карты */
|
||||||
|
&test_rtc,
|
||||||
|
&test_display, /* operator confirm */
|
||||||
|
&test_ir, /* self-test уровень */
|
||||||
|
&test_can, /* requires_hil */
|
||||||
|
&test_uart_ttl, /* requires_hil */
|
||||||
|
&test_uart_iso, /* requires_hil */
|
||||||
|
&test_opto, /* requires_hil */
|
||||||
|
&test_ir_hil, /* requires_hil, SKIP если нет IR на стенде */
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Статусы тестов
|
||||||
|
|
||||||
|
| Статус | Значение |
|
||||||
|
|--------|-------------------------------------------------------|
|
||||||
|
| `PASS` | Тест прошёл успешно |
|
||||||
|
| `FAIL` | Тест провален, в `detail` диагностическая информация |
|
||||||
|
| `SKIP` | Тест пропущен (нет карты, нет Firefly, таймаут оператора) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Открытые вопросы
|
||||||
|
|
||||||
|
- [ ] Формат `detail` при FAIL для каждого теста (договориться между разработчиками)
|
||||||
|
- [ ] Handshake-протокол между firmware_test и Firefly (как плата узнаёт о готовности стенда)
|
||||||
|
- [ ] Полная схема интерфейсной платы для Firefly (оптовходы, IR LED, уровни +24V)
|
||||||
|
- [ ] GUI на сервере: формат отображения `summary` и хранение истории плат
|
||||||
268
firmware/test/arch.svg
Normal file
268
firmware/test/arch.svg
Normal file
|
|
@ -0,0 +1,268 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="1360" viewBox="0 0 680 1180">
|
||||||
|
<defs>
|
||||||
|
<marker id="arrow" viewBox="0 0 10 10" refX="8" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse">
|
||||||
|
<path d="M2 1L8 5L2 9" fill="none" stroke="context-stroke" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</marker>
|
||||||
|
<style>
|
||||||
|
text { font-family: system-ui, sans-serif; fill: #1a1a1a; }
|
||||||
|
.th { font-size: 14px; font-weight: 500; }
|
||||||
|
.ts { font-size: 12px; font-weight: 400; fill: #555; }
|
||||||
|
.label-section { font-size: 11px; font-weight: 400; fill: #888; }
|
||||||
|
|
||||||
|
/* teal */
|
||||||
|
.c-teal rect, .c-teal circle { fill: #E1F5EE; stroke: #0F6E56; }
|
||||||
|
.c-teal .th { fill: #085041; }
|
||||||
|
.c-teal .ts { fill: #0F6E56; }
|
||||||
|
|
||||||
|
/* purple */
|
||||||
|
.c-purple rect { fill: #EEEDFE; stroke: #534AB7; }
|
||||||
|
.c-purple .th { fill: #3C3489; }
|
||||||
|
.c-purple .ts { fill: #534AB7; }
|
||||||
|
|
||||||
|
/* amber */
|
||||||
|
.c-amber rect { fill: #FAEEDA; stroke: #854F0B; }
|
||||||
|
.c-amber .th { fill: #633806; }
|
||||||
|
.c-amber .ts { fill: #854F0B; }
|
||||||
|
|
||||||
|
/* gray */
|
||||||
|
.c-gray rect { fill: #F1EFE8; stroke: #5F5E5A; }
|
||||||
|
.c-gray .th { fill: #2C2C2A; }
|
||||||
|
.c-gray .ts { fill: #5F5E5A; }
|
||||||
|
|
||||||
|
/* red */
|
||||||
|
.c-red rect { fill: #FCEBEB; stroke: #A32D2D; }
|
||||||
|
.c-red .th { fill: #501313; }
|
||||||
|
.c-red .ts { fill: #A32D2D; }
|
||||||
|
|
||||||
|
.arr { stroke: #888; stroke-width: 1; fill: none; }
|
||||||
|
.box-dashed { fill: none; stroke: #bbb; stroke-width: 0.8; stroke-dasharray: 5 3; }
|
||||||
|
</style>
|
||||||
|
</defs>
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════════════════════
|
||||||
|
DIAGRAM 1: High-level architecture
|
||||||
|
═══════════════════════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<text x="340" y="30" text-anchor="middle" class="th" style="font-size:16px;fill:#1a1a1a;">firmware_test · high-level architecture</text>
|
||||||
|
<text x="340" y="48" text-anchor="middle" class="ts">NXP IMXRT1052CVJ5B</text>
|
||||||
|
|
||||||
|
<rect x="20" y="60" width="640" height="440" rx="16" class="box-dashed"/>
|
||||||
|
<text x="340" y="78" text-anchor="middle" class="label-section">firmware_test</text>
|
||||||
|
|
||||||
|
<!-- USB CDC -->
|
||||||
|
<g class="c-teal">
|
||||||
|
<rect x="40" y="88" width="160" height="50" rx="8" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="120" y="108" text-anchor="middle" dominant-baseline="central">USB CDC</text>
|
||||||
|
<text class="ts" x="120" y="126" text-anchor="middle" dominant-baseline="central">virtual serial port</text>
|
||||||
|
</g>
|
||||||
|
<text class="ts" x="212" y="107" fill="#888">↔ Host PC</text>
|
||||||
|
<text class="ts" x="212" y="123" fill="#888">(терминал / GUI)</text>
|
||||||
|
|
||||||
|
<line x1="120" y1="138" x2="120" y2="180" class="arr" marker-end="url(#arrow)"/>
|
||||||
|
|
||||||
|
<!-- Protocol -->
|
||||||
|
<g class="c-purple">
|
||||||
|
<rect x="40" y="180" width="160" height="50" rx="8" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="120" y="200" text-anchor="middle" dominant-baseline="central">Protocol</text>
|
||||||
|
<text class="ts" x="120" y="218" text-anchor="middle" dominant-baseline="central">JSON-lines · cJSON</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Test runner -->
|
||||||
|
<g class="c-purple">
|
||||||
|
<rect x="250" y="180" width="190" height="50" rx="8" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="345" y="200" text-anchor="middle" dominant-baseline="central">Test runner</text>
|
||||||
|
<text class="ts" x="345" y="218" text-anchor="middle" dominant-baseline="central">sequencer + registry</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- Local UI -->
|
||||||
|
<g class="c-amber">
|
||||||
|
<rect x="490" y="180" width="150" height="50" rx="8" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="565" y="200" text-anchor="middle" dominant-baseline="central">Local UI</text>
|
||||||
|
<text class="ts" x="565" y="218" text-anchor="middle" dominant-baseline="central">LEDs + display</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<line x1="200" y1="205" x2="250" y2="205" class="arr" marker-start="url(#arrow)" marker-end="url(#arrow)" stroke="#666"/>
|
||||||
|
<line x1="440" y1="205" x2="490" y2="205" class="arr" marker-end="url(#arrow)" stroke="#666"/>
|
||||||
|
|
||||||
|
<path d="M345,230 L345,260 L180,260 L180,270" fill="none" stroke="#bbb" stroke-width="0.8" marker-end="url(#arrow)"/>
|
||||||
|
<path d="M345,230 L345,260 L505,260 L505,270" fill="none" stroke="#bbb" stroke-width="0.8" marker-end="url(#arrow)"/>
|
||||||
|
|
||||||
|
<!-- Self-tests region -->
|
||||||
|
<rect x="30" y="270" width="300" height="150" rx="8" class="box-dashed"/>
|
||||||
|
<text class="label-section" x="56" y="287">self-tests</text>
|
||||||
|
|
||||||
|
<g class="c-gray"><rect x="46" y="295" width="76" height="44" rx="6" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="84" y="312" text-anchor="middle" dominant-baseline="central">SDRAM</text>
|
||||||
|
<text class="ts" x="84" y="328" text-anchor="middle" dominant-baseline="central">32 MB</text></g>
|
||||||
|
<g class="c-gray"><rect x="132" y="295" width="76" height="44" rx="6" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="170" y="312" text-anchor="middle" dominant-baseline="central">QSPI</text>
|
||||||
|
<text class="ts" x="170" y="328" text-anchor="middle" dominant-baseline="central">W25Q128</text></g>
|
||||||
|
<g class="c-gray"><rect x="218" y="295" width="76" height="44" rx="6" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="256" y="312" text-anchor="middle" dominant-baseline="central">uSD</text>
|
||||||
|
<text class="ts" x="256" y="328" text-anchor="middle" dominant-baseline="central">SDIO</text></g>
|
||||||
|
<g class="c-gray"><rect x="46" y="349" width="76" height="44" rx="6" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="84" y="366" text-anchor="middle" dominant-baseline="central">RTC</text>
|
||||||
|
<text class="ts" x="84" y="382" text-anchor="middle" dominant-baseline="central">BM8563</text></g>
|
||||||
|
<g class="c-gray"><rect x="132" y="349" width="76" height="44" rx="6" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="170" y="366" text-anchor="middle" dominant-baseline="central">Display</text>
|
||||||
|
<text class="ts" x="170" y="382" text-anchor="middle" dominant-baseline="central">operator ✓</text></g>
|
||||||
|
<g class="c-gray"><rect x="218" y="349" width="76" height="44" rx="6" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="256" y="366" text-anchor="middle" dominant-baseline="central">IR</text>
|
||||||
|
<text class="ts" x="256" y="382" text-anchor="middle" dominant-baseline="central">idle GPIO</text></g>
|
||||||
|
|
||||||
|
<!-- HIL tests region -->
|
||||||
|
<rect x="350" y="270" width="290" height="150" rx="8" class="box-dashed"/>
|
||||||
|
<text class="label-section" x="376" y="287">HIL tests · Firefly AIO-3588Q</text>
|
||||||
|
|
||||||
|
<g class="c-teal"><rect x="366" y="295" width="120" height="44" rx="6" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="426" y="312" text-anchor="middle" dominant-baseline="central">CAN</text>
|
||||||
|
<text class="ts" x="426" y="328" text-anchor="middle" dominant-baseline="central">frame exchange</text></g>
|
||||||
|
<g class="c-teal"><rect x="496" y="295" width="120" height="44" rx="6" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="556" y="312" text-anchor="middle" dominant-baseline="central">UART TTL</text>
|
||||||
|
<text class="ts" x="556" y="328" text-anchor="middle" dominant-baseline="central">echo pattern</text></g>
|
||||||
|
<g class="c-teal"><rect x="366" y="349" width="120" height="44" rx="6" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="426" y="366" text-anchor="middle" dominant-baseline="central">UART ISO</text>
|
||||||
|
<text class="ts" x="426" y="382" text-anchor="middle" dominant-baseline="central">+24V RX only</text></g>
|
||||||
|
<g class="c-teal"><rect x="496" y="349" width="120" height="44" rx="6" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="556" y="366" text-anchor="middle" dominant-baseline="central">Opto-in</text>
|
||||||
|
<text class="ts" x="556" y="382" text-anchor="middle" dominant-baseline="central">+24V all ch.</text></g>
|
||||||
|
|
||||||
|
<!-- HAL / BSP -->
|
||||||
|
<line x1="340" y1="420" x2="340" y2="448" class="arr" marker-end="url(#arrow)" stroke="#aaa"/>
|
||||||
|
<g class="c-gray">
|
||||||
|
<rect x="30" y="448" width="620" height="40" rx="8" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="340" y="468" text-anchor="middle" dominant-baseline="central">HAL / BSP</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<!-- ═══════════════════════════════════════════════════════
|
||||||
|
DIAGRAM 2: Test runner flow
|
||||||
|
═══════════════════════════════════════════════════════ -->
|
||||||
|
|
||||||
|
<text x="340" y="540" text-anchor="middle" class="th" style="font-size:16px;fill:#1a1a1a;">firmware_test · test runner flow</text>
|
||||||
|
|
||||||
|
<!-- Boot -->
|
||||||
|
<g class="c-gray">
|
||||||
|
<rect x="240" y="558" width="200" height="44" rx="8" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="340" y="576" text-anchor="middle" dominant-baseline="central">Boot</text>
|
||||||
|
<text class="ts" x="340" y="592" text-anchor="middle" dominant-baseline="central">clock, USB CDC, HAL init</text>
|
||||||
|
</g>
|
||||||
|
<line x1="340" y1="602" x2="340" y2="630" class="arr" marker-end="url(#arrow)" stroke="#888"/>
|
||||||
|
|
||||||
|
<!-- Wait for host -->
|
||||||
|
<g class="c-purple">
|
||||||
|
<rect x="240" y="630" width="200" height="44" rx="8" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="340" y="648" text-anchor="middle" dominant-baseline="central">Wait for host</text>
|
||||||
|
<text class="ts" x="340" y="664" text-anchor="middle" dominant-baseline="central">USB connect or timeout</text>
|
||||||
|
</g>
|
||||||
|
<line x1="340" y1="674" x2="340" y2="698" class="arr" marker-end="url(#arrow)" stroke="#888"/>
|
||||||
|
|
||||||
|
<!-- Self-tests block -->
|
||||||
|
<rect x="30" y="698" width="620" height="168" rx="10" class="box-dashed"/>
|
||||||
|
<text class="label-section" x="56" y="714">self-tests</text>
|
||||||
|
|
||||||
|
<g class="c-red">
|
||||||
|
<rect x="46" y="720" width="110" height="54" rx="6" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="101" y="740" text-anchor="middle" dominant-baseline="central">SDRAM</text>
|
||||||
|
<text class="ts" x="101" y="756" text-anchor="middle" dominant-baseline="central">critical</text>
|
||||||
|
<text class="ts" x="101" y="768" text-anchor="middle" dominant-baseline="central">write/read pattern</text>
|
||||||
|
</g>
|
||||||
|
<g class="c-red">
|
||||||
|
<rect x="166" y="720" width="110" height="54" rx="6" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="221" y="740" text-anchor="middle" dominant-baseline="central">QSPI Flash</text>
|
||||||
|
<text class="ts" x="221" y="756" text-anchor="middle" dominant-baseline="central">critical</text>
|
||||||
|
<text class="ts" x="221" y="768" text-anchor="middle" dominant-baseline="central">JEDEC ID + R/W</text>
|
||||||
|
</g>
|
||||||
|
<g class="c-red">
|
||||||
|
<rect x="286" y="720" width="110" height="54" rx="6" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="341" y="740" text-anchor="middle" dominant-baseline="central">uSD</text>
|
||||||
|
<text class="ts" x="341" y="756" text-anchor="middle" dominant-baseline="central">critical</text>
|
||||||
|
<text class="ts" x="341" y="768" text-anchor="middle" dominant-baseline="central">mount + R/W</text>
|
||||||
|
</g>
|
||||||
|
<g class="c-gray">
|
||||||
|
<rect x="406" y="720" width="110" height="54" rx="6" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="461" y="740" text-anchor="middle" dominant-baseline="central">RTC</text>
|
||||||
|
<text class="ts" x="461" y="756" text-anchor="middle" dominant-baseline="central">I2C presence</text>
|
||||||
|
<text class="ts" x="461" y="768" text-anchor="middle" dominant-baseline="central">set / get</text>
|
||||||
|
</g>
|
||||||
|
<g class="c-amber">
|
||||||
|
<rect x="526" y="720" width="110" height="54" rx="6" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="581" y="740" text-anchor="middle" dominant-baseline="central">Display</text>
|
||||||
|
<text class="ts" x="581" y="756" text-anchor="middle" dominant-baseline="central">R/G/B/W fill</text>
|
||||||
|
<text class="ts" x="581" y="768" text-anchor="middle" dominant-baseline="central">btn confirm</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<line x1="101" y1="774" x2="101" y2="794" class="arr" marker-end="url(#arrow)" stroke="#888"/>
|
||||||
|
<line x1="221" y1="774" x2="221" y2="794" class="arr" marker-end="url(#arrow)" stroke="#888"/>
|
||||||
|
<line x1="341" y1="774" x2="341" y2="794" class="arr" marker-end="url(#arrow)" stroke="#888"/>
|
||||||
|
<line x1="461" y1="774" x2="461" y2="794" class="arr" marker-end="url(#arrow)" stroke="#888"/>
|
||||||
|
<line x1="581" y1="774" x2="581" y2="794" class="arr" marker-end="url(#arrow)" stroke="#888"/>
|
||||||
|
|
||||||
|
<!-- Check critical failures -->
|
||||||
|
<g class="c-gray">
|
||||||
|
<rect x="46" y="794" width="590" height="44" rx="6" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="341" y="812" text-anchor="middle" dominant-baseline="central">Check critical failures</text>
|
||||||
|
<text class="ts" x="341" y="828" text-anchor="middle" dominant-baseline="central">SDRAM || QSPI || uSD FAIL → abort HIL, report immediately</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<line x1="340" y1="866" x2="340" y2="890" class="arr" marker-end="url(#arrow)" stroke="#888"/>
|
||||||
|
|
||||||
|
<!-- HIL block -->
|
||||||
|
<rect x="30" y="890" width="620" height="78" rx="10" class="box-dashed"/>
|
||||||
|
<text class="label-section" x="56" y="906">HIL tests · requires Firefly</text>
|
||||||
|
|
||||||
|
<g class="c-teal">
|
||||||
|
<rect x="46" y="912" width="100" height="44" rx="6" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="96" y="930" text-anchor="middle" dominant-baseline="central">CAN</text>
|
||||||
|
<text class="ts" x="96" y="946" text-anchor="middle" dominant-baseline="central">full-duplex</text>
|
||||||
|
</g>
|
||||||
|
<g class="c-teal">
|
||||||
|
<rect x="156" y="912" width="100" height="44" rx="6" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="206" y="930" text-anchor="middle" dominant-baseline="central">UART TTL</text>
|
||||||
|
<text class="ts" x="206" y="946" text-anchor="middle" dominant-baseline="central">echo</text>
|
||||||
|
</g>
|
||||||
|
<g class="c-teal">
|
||||||
|
<rect x="266" y="912" width="100" height="44" rx="6" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="316" y="930" text-anchor="middle" dominant-baseline="central">UART ISO</text>
|
||||||
|
<text class="ts" x="316" y="946" text-anchor="middle" dominant-baseline="central">RX only</text>
|
||||||
|
</g>
|
||||||
|
<g class="c-teal">
|
||||||
|
<rect x="376" y="912" width="100" height="44" rx="6" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="426" y="930" text-anchor="middle" dominant-baseline="central">Opto-in</text>
|
||||||
|
<text class="ts" x="426" y="946" text-anchor="middle" dominant-baseline="central">all channels</text>
|
||||||
|
</g>
|
||||||
|
<g class="c-gray">
|
||||||
|
<rect x="486" y="912" width="100" height="44" rx="6" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="536" y="930" text-anchor="middle" dominant-baseline="central">IR burst</text>
|
||||||
|
<text class="ts" x="536" y="946" text-anchor="middle" dominant-baseline="central">38 kHz RX</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<line x1="340" y1="968" x2="340" y2="996" class="arr" marker-end="url(#arrow)" stroke="#888"/>
|
||||||
|
|
||||||
|
<!-- Summary -->
|
||||||
|
<g class="c-teal">
|
||||||
|
<rect x="160" y="996" width="360" height="50" rx="8" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="340" y="1016" text-anchor="middle" dominant-baseline="central">Summary report</text>
|
||||||
|
<text class="ts" x="340" y="1034" text-anchor="middle" dominant-baseline="central">JSON · pass/fail/skip per test · overall</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<line x1="340" y1="1046" x2="340" y2="1074" class="arr" marker-end="url(#arrow)" stroke="#aaa" stroke-dasharray="4 3"/>
|
||||||
|
|
||||||
|
<!-- Provisioning -->
|
||||||
|
<g class="c-purple">
|
||||||
|
<rect x="160" y="1074" width="360" height="50" rx="8" stroke-width="0.5"/>
|
||||||
|
<text class="th" x="340" y="1094" text-anchor="middle" dominant-baseline="central">Provisioning</text>
|
||||||
|
<text class="ts" x="340" y="1112" text-anchor="middle" dominant-baseline="central">OCOTP chip_uid → host DB · only on pass</text>
|
||||||
|
</g>
|
||||||
|
|
||||||
|
<text class="ts" x="536" y="1050" fill="#aaa">only if overall == pass</text>
|
||||||
|
|
||||||
|
<!-- Legend -->
|
||||||
|
<rect x="30" y="1140" width="260" height="30" rx="6" fill="none" stroke="#eee" stroke-width="0.5"/>
|
||||||
|
<rect x="40" y="1151" width="12" height="8" rx="2" fill="#FCEBEB" stroke="#A32D2D" stroke-width="0.5"/>
|
||||||
|
<text class="ts" x="58" y="1159">critical test</text>
|
||||||
|
<rect x="130" y="1151" width="12" height="8" rx="2" fill="#E1F5EE" stroke="#0F6E56" stroke-width="0.5"/>
|
||||||
|
<text class="ts" x="148" y="1159">HIL test</text>
|
||||||
|
<rect x="200" y="1151" width="12" height="8" rx="2" fill="#FAEEDA" stroke="#854F0B" stroke-width="0.5"/>
|
||||||
|
<text class="ts" x="218" y="1159">operator</text>
|
||||||
|
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 15 KiB |
Loading…
Reference in a new issue