From 0fdbeffda5e82ef0bc55158717ce45a821908580 Mon Sep 17 00:00:00 2001 From: David Montero Crespo Date: Wed, 6 May 2026 15:48:05 -0300 Subject: [PATCH] docs: add ESP32-P4 research and feasibility report Investigation into adding ESP32-P4 to Velxio via either of the two existing emulation paths (frontend JS/WASM or backend QEMU/WebSocket). Verified the arduino-cli toolchain works (RISC-V 32-bit ELF, RVC, single-float ABI), but both emulation paths are blocked upstream: - espressif/qemu has no esp32p4 machine yet (issue #127, status: To Do). - No open-source JS/WASM ESP32 emulator exists; Wokwi's engine is closed. Includes a smoke-test script ready for the day the Espressif QEMU machine lands, plus a Phase A/B/C plan in autosearch/06_recommendations.md. Co-Authored-By: Claude Opus 4.7 (1M context) --- test/test-esp32-p4/.gitignore | 2 + test/test-esp32-p4/README.md | 50 ++++++++++++ test/test-esp32-p4/autosearch/01_findings.md | 66 +++++++++++++++ .../autosearch/02_chip_overview.md | 69 ++++++++++++++++ .../autosearch/03_compilation_test.md | 73 +++++++++++++++++ .../autosearch/04_qemu_backend_path.md | 80 +++++++++++++++++++ .../autosearch/05_frontend_emulation_path.md | 61 ++++++++++++++ .../autosearch/06_recommendations.md | 61 ++++++++++++++ test/test-esp32-p4/scripts/compile.sh | 18 +++++ test/test-esp32-p4/scripts/smoke_qemu.sh | 44 ++++++++++ test/test-esp32-p4/sketches/blink/blink.ino | 19 +++++ 11 files changed, 543 insertions(+) create mode 100644 test/test-esp32-p4/.gitignore create mode 100644 test/test-esp32-p4/README.md create mode 100644 test/test-esp32-p4/autosearch/01_findings.md create mode 100644 test/test-esp32-p4/autosearch/02_chip_overview.md create mode 100644 test/test-esp32-p4/autosearch/03_compilation_test.md create mode 100644 test/test-esp32-p4/autosearch/04_qemu_backend_path.md create mode 100644 test/test-esp32-p4/autosearch/05_frontend_emulation_path.md create mode 100644 test/test-esp32-p4/autosearch/06_recommendations.md create mode 100644 test/test-esp32-p4/scripts/compile.sh create mode 100644 test/test-esp32-p4/scripts/smoke_qemu.sh create mode 100644 test/test-esp32-p4/sketches/blink/blink.ino diff --git a/test/test-esp32-p4/.gitignore b/test/test-esp32-p4/.gitignore new file mode 100644 index 00000000..027c3f49 --- /dev/null +++ b/test/test-esp32-p4/.gitignore @@ -0,0 +1,2 @@ +sketches/*/build/ +binaries/ diff --git a/test/test-esp32-p4/README.md b/test/test-esp32-p4/README.md new file mode 100644 index 00000000..01337999 --- /dev/null +++ b/test/test-esp32-p4/README.md @@ -0,0 +1,50 @@ +# test-esp32-p4 — investigación de soporte ESP32-P4 en Velxio + +Sandbox de investigación para evaluar si el chip Espressif **ESP32-P4** puede sumarse a Velxio como board emulable. + +## Contexto + +Velxio hoy tiene **dos vías** de emulación: + +1. **Frontend (browser)** — JS puro / WASM. Cubre AVR (`avr8js`) y RP2040 (`rp2040js`). +2. **Backend WebSocket → QEMU** — proceso QEMU por cliente, UART y GPIO chardev sobre TCP. Cubre ESP32, ESP32-S3 (Xtensa) y ESP32-C3 (RISC-V). + +Ver `backend/app/services/esp_qemu_manager.py` para el pattern actual. + +## Estructura + +``` +test-esp32-p4/ +├── README.md # este archivo +├── autosearch/ # hallazgos, qué funciona / qué no +│ ├── 01_findings.md +│ ├── 02_chip_overview.md +│ ├── 03_compilation_test.md +│ ├── 04_qemu_backend_path.md +│ ├── 05_frontend_emulation_path.md +│ └── 06_recommendations.md +├── sketches/blink/blink.ino # sketch mínimo Arduino para esp32:esp32:esp32p4 +├── binaries/ # outputs de compilación (gitignore-able) +└── scripts/ # scripts de test (vacío) +``` + +## TL;DR + +- ✅ **Compilación funciona** con `arduino-cli` + core `esp32:esp32 3.3.8`. FQBN `esp32:esp32:esp32p4` produce ELF RISC-V 32-bit (RVC, single-float ABI) y `merged.bin` de 4 MB. +- ❌ **No hay máquina QEMU para ESP32-P4** en `espressif/qemu` (último release `esp-develop-9.2.2-20260417`). Soporte es "To Do" — ver [issue #127](https://github.com/espressif/qemu/issues/127). +- ❌ **No hay emulador JS/WASM open-source** del ESP32-P4. Wokwi tiene simulador beta cerrado (`board-esp32-p4-preview`); su engine no es público. +- ⚠️ La vía realista de hoy es **esperar el merge de la máquina P4 en `espressif/qemu`** y, mientras tanto, dejar la pieza de toolchain (compilación + flashing args) lista en backend y agregar el board element visual (placeholder) en frontend. + +Detalles: [`autosearch/06_recommendations.md`](autosearch/06_recommendations.md). + +## Reproducir el test de compilación + +```bash +cd test/test-esp32-p4/sketches +arduino-cli core install esp32:esp32 # si no está instalado +arduino-cli compile --fqbn esp32:esp32:esp32p4 blink +ls blink/build/esp32.esp32.esp32p4/ +# blink.ino.elf, blink.ino.bin, blink.ino.merged.bin (4 MB), bootloader, partitions +file blink/build/esp32.esp32.esp32p4/blink.ino.elf +# → ELF 32-bit LSB executable, UCB RISC-V, RVC, single-float ABI +``` diff --git a/test/test-esp32-p4/autosearch/01_findings.md b/test/test-esp32-p4/autosearch/01_findings.md new file mode 100644 index 00000000..24e7aaf7 --- /dev/null +++ b/test/test-esp32-p4/autosearch/01_findings.md @@ -0,0 +1,66 @@ +# 01 — Hallazgos sesión 2026-05-06 + +## Resumen ejecutivo + +Sumar ESP32-P4 a Velxio **no es posible hoy con la arquitectura existente** (ni vía backend QEMU ni vía emulador JS frontend), pero **el toolchain de compilación ya funciona** y no hay obstáculo de licencia ni de toolchain. La pieza bloqueante es **la máquina QEMU `esp32p4`**: Espressif aún no la ha implementado en su fork. Wokwi sí simula el chip, pero su engine es propietario. + +Recomendación: dejar la rama de **compilación + ELF** lista en backend (cambios mínimos en `arduino_cli.py` y `esp_qemu_manager.py`), y poner el board en estado "compilable, no emulable" hasta que `espressif/qemu` libere la máquina P4. Más detalle en [`06_recommendations.md`](06_recommendations.md). + +## Lo que funciona (verificado en esta máquina) + +| Pieza | Estado | Evidencia | +|---|---|---| +| Detección de boards ESP32-P4 en `arduino-cli` | ✅ | `arduino-cli board listall` lista 5 variantes (Dev Module, Core Board, FireBeetle 2, 4D Systems MIPI). | +| Core `esp32:esp32 3.3.8` instalado y soporta P4 | ✅ | Ya estaba instalado en el entorno. | +| Compilación de blink mínimo | ✅ | `arduino-cli compile --fqbn esp32:esp32:esp32p4 blink` → exit 0. | +| Output ELF RISC-V 32-bit (RVC, single-float) | ✅ | `file blink.ino.elf` → `ELF 32-bit LSB executable, UCB RISC-V, RVC, single-float ABI`. | +| Tamaños razonables | ✅ | sketch 312 KB / 1310 KB flash; globals 21 KB / 327 KB SRAM. | +| `merged.bin` 4 MB con bootloader + app + partitions | ✅ | Listo para `qemu -drive if=mtd,format=raw` igual que ESP32/C3. | +| arduino-esp32 v3.1.x soporta P4 | ✅ | Confirmado en [arduino-esp32 #10278](https://github.com/espressif/arduino-esp32/issues/10278): GPIO/I2C/SPI/UART/Wi-Fi (vía co-procesador externo)/USB OK. Faltan ADC calibration, BT Classic, DAC, Hall, MCPWM, PCNT, MIPI, MSPI. | + +## Lo que NO funciona (bloqueantes) + +| Bloqueante | Estado | Por qué | +|---|---|---| +| **Máquina `esp32p4` en `espressif/qemu`** | ❌ | Último release `esp-develop-9.2.2` (2026-04-17) lista solo `esp32`, `esp32-s3`, `esp32c3`. [Issue #127](https://github.com/espressif/qemu/issues/127) abierto desde 2025-05-17, label `Status: To Do`. La carpeta `hw/riscv` del fork solo tiene `esp32c3.c`. | +| **Forks alternativos QEMU con P4** | ❌ | Revisados: `lcgamboa/qemu` (PICSimLab), `Ebiroll/qemu_esp32`, `epiclabs-uc/qemu-esp32`, `max1220/qemu-esp32`. Ninguno menciona P4. | +| **Emulador JS/WASM open-source** | ❌ | Wokwi tiene `avr8js` y `rp2040js` públicos, pero **no** existe `esp32js` o `esp32p4js` open-source. Wokwi simula P4 en beta dentro de su producto cerrado. | +| **Wokwi-elements board element** | ❌ | `wokwi-libs/wokwi-elements/src/` tiene `esp32-devkit-v1-element.ts` pero no `esp32-p4`. El `board-esp32-p4-preview` que aparece en `diagram.json` de Wokwi vive solo en su build privado. | +| **QEMU instalado localmente para smoke test** | ❌ | `qemu-system-riscv32` no está en PATH en esta máquina. El smoke test contra P4 sería igual fútil porque la máquina ni siquiera existe en el binario. | + +## Lo que probé (timeline) + +1. Compilación local: **OK**, ELF y `merged.bin` generados (ver `03_compilation_test.md`). +2. Búsqueda en `espressif/qemu`: branches (`esp-develop`, `esp-develop-based-on-9.2.2`, `master`) y carpeta `hw/riscv` → ningún archivo `esp32p4*`. [Issue #127](https://github.com/espressif/qemu/issues/127) es la fuente única de verdad: status "To Do". +3. Búsqueda en wokwi-elements: solo `esp32-devkit-v1-element.ts`, sin variante P4. +4. Búsqueda en organización `wokwi` de GitHub: hay `esp32p4-hello-world` y `esp32p4-mipi-dsi-panel-demo` (solo sketches de ejemplo), no engine. +5. Wokwi docs (`/guides/esp32`): confirma que P4 está "in beta" en Wokwi pero sin detalles del engine. + +## Implicaciones para Velxio + +1. **Backend (`esp_qemu_manager.py`)**: agregar `'esp32-p4': (QEMU_RISCV32, 'esp32p4')` cuando la máquina exista. Bootloader offset y flash layout ya son los mismos del C3 (offset 0x0000, no 0x1000 — patrón ya implementado en `arduino_cli.py:369`). +2. **Frontend (`types/board.ts`)**: agregar `'esp32-p4'` al `BoardKind`. Es **RISC-V**, igual que C3 → entra en el flujo de WebSocket-QEMU, **no** en el flujo browser-emulado (avr8js / rp2040js). +3. **Cosmético**: dibujar un board element. Sin un SVG de wokwi-elements, hay que crear el componente nuevo (ya hay precedente con `esp32-cam` y `wemos-lolin32-lite` que reutilizan el SVG ESP32 base con pin labels distintos). +4. **MicroPython**: el set `BOARD_SUPPORTS_MICROPYTHON` debería incluir `esp32-p4` cuando QEMU corra (MicroPython oficial ya tiene puerto P4). + +## Riesgos + +- **Wi-Fi/BLE**: el ESP32-P4 no tiene radio. Las plataformas (FireBeetle 2, ESP32-P4-Module) lo combinan con un **ESP32-C6** externo vía SDIO/UART. Esto rompe el modelo NIC actual (`esp32_wifi`, `esp32c3_wifi`). Cuando llegue el QEMU, hay que decidir: (a) modelar también el C6 companion, (b) marcar Wi-Fi como no-emulado y mostrar warning al usuario. +- **MIPI-DSI / CSI**: el chip los tiene, pero ningún emulador (ni siquiera Wokwi) los simula a fondo. Sería out-of-scope. +- **PSRAM**: hasta 32 MB. QEMU puede hacerlo (-m), no es bloqueante. + +## Archivos relacionados + +- [`02_chip_overview.md`](02_chip_overview.md) — specs y peripherals +- [`03_compilation_test.md`](03_compilation_test.md) — output exacto de la compilación +- [`04_qemu_backend_path.md`](04_qemu_backend_path.md) — qué hace falta en backend cuando QEMU soporte P4 +- [`05_frontend_emulation_path.md`](05_frontend_emulation_path.md) — opciones JS/WASM y por qué descartadas +- [`06_recommendations.md`](06_recommendations.md) — plan accionable + +## Fuentes + +- [arduino-esp32 — Support of ESP32-P4 (#10278)](https://github.com/espressif/arduino-esp32/issues/10278) +- [espressif/qemu — Is QEMU support planned for esp32p4 and esp32c6? (#127)](https://github.com/espressif/qemu/issues/127) +- [espressif/qemu releases](https://github.com/espressif/qemu/releases) +- [Wokwi ESP32 Simulation guide](https://docs.wokwi.com/guides/esp32) +- [ESP32-P4 product page](https://www.espressif.com/en/products/socs/esp32-p4) diff --git a/test/test-esp32-p4/autosearch/02_chip_overview.md b/test/test-esp32-p4/autosearch/02_chip_overview.md new file mode 100644 index 00000000..44c92e7c --- /dev/null +++ b/test/test-esp32-p4/autosearch/02_chip_overview.md @@ -0,0 +1,69 @@ +# 02 — ESP32-P4 chip overview + +## Procesador + +- **HP core**: dual-core RISC-V hasta **400 MHz** (RV32IMAFC + extensiones AI propietarias de Espressif). +- **LP core**: RISC-V single-core hasta **40 MHz** (low-power, similar al ULP coprocessor de otros ESP32). +- ABI: `ilp32f` (single-precision FPU) — confirmado por `file blink.ino.elf` → "RVC, single-float ABI". +- ISA real observada en el ELF: **RV32IMC** (compressed) + soft-float a nivel de Arduino core (el FPU está pero arduino-esp32 aún no lo usa universalmente). + +## Memoria + +- **768 KB SRAM HP** on-chip (utilizable como cache cuando hay PSRAM). +- **8 KB TCM RAM** zero-wait. +- Soporta **PSRAM externa hasta 32 MB**. +- Flash externa SPI (típicamente QSPI, hasta 16/32 MB en dev kits). + +## Sin radio integrado + +⚠️ **El P4 NO tiene Wi-Fi ni Bluetooth nativos**. Los dev kits (FireBeetle 2 ESP32-P4, ESP32-P4-Module, ESP32-P4-NANO) llevan un **ESP32-C6 externo** conectado por SDIO/UART para Wi-Fi 6 y BLE. + +Implicación para emulación: el modelo NIC `esp32_wifi` / `esp32c3_wifi` que usa el `esp_qemu_manager` actual **no aplica directamente**. Habría que: +- (a) emular el bus SDIO/UART hacia un C6 emulado (complejo, no existe), +- (b) interceptar la API de IDF/Arduino (`WiFi.begin()`, etc.) y devolver mocks (ya hay un patrón parecido en `wifi_status_parser.py`). + +## Periféricos relevantes para Velxio + +| Periférico | Cantidad | Uso típico Velxio | +|---|---|---| +| GPIO | 55 (vs 22 en ESP32) | LED, botón, sensor digital | +| ADC | 7 ch × 2 unidades, 12-bit | sensores analógicos, potenciómetro | +| I²C | 2 master / 1 slave | sensores BMP280, MPU6050, LCD I²C | +| SPI | 3 (uno dedicado a flash/PSRAM) | display TFT, SD card | +| I²S | 3 | audio | +| UART | 5 | serial monitor + comms externos | +| LEDC PWM | 8 ch | LED brillo, servos | +| MCPWM | 2 | motor control | +| RMT | 4 ch | NeoPixel, IR | +| USB OTG 2.0 HS | 1 | host/device, **480 Mbps** | +| Ethernet | 1 (RMII) | Ethernet en dev kits | +| SDIO Host | 1 (3.0) | SD card / Wi-Fi co-proc | +| **MIPI-CSI** | 1 (1080p) | cámara — **no emulable** | +| **MIPI-DSI** | 1 (1080p) | display — **no emulable hoy** | + +## Variantes de board en arduino-cli (verificadas) + +``` +esp32:esp32:esp32p4 # ESP32P4 Dev Module (genérico) +esp32:esp32:esp32p4_core_board # ESP32P4 Core Board +esp32:esp32:dfrobot_firebeetle2_esp32p4 # DFRobot FireBeetle 2 ESP32-P4 +esp32:esp32:esp32p4_4ds_mipi # 4D Systems ESP32-P4 MIPI Displays +esp32:esp32:esp32p4_4ds_mipi_round # 4D Systems redondo +``` + +Para Velxio, el FQBN canónico debería ser `esp32:esp32:esp32p4` (Dev Module) — paralelo a `esp32:esp32:esp32` para el clásico. + +## Comparativa con boards ya soportados en Velxio + +| Board | Arch | Dónde corre hoy | +|---|---|---| +| Arduino Uno (atmega328p) | AVR 8-bit | frontend (avr8js) | +| ATtiny85 | AVR 8-bit | frontend (avr8js) | +| Raspberry Pi Pico (RP2040) | ARM Cortex-M0+ dual | frontend (rp2040js) | +| ESP32 | Xtensa LX6 dual | backend QEMU xtensa | +| ESP32-S3 | Xtensa LX7 dual | backend QEMU xtensa | +| ESP32-C3 | RISC-V RV32IMC single | backend QEMU riscv32 | +| Raspberry Pi 3B | ARM64 | backend QEMU aarch64 | +| **ESP32-P4** | **RISC-V RV32IMAFC dual + LP** | **backend QEMU riscv32 (cuando exista)** | + +El ESP32-P4 cae en la **misma categoría que el ESP32-C3**: backend, `qemu-system-riscv32`, `-M esp32p4`. Reutiliza casi toda la plomería del C3 (UART por TCP, GPIO chardev, NIC slirp si llega Wi-Fi). diff --git a/test/test-esp32-p4/autosearch/03_compilation_test.md b/test/test-esp32-p4/autosearch/03_compilation_test.md new file mode 100644 index 00000000..b6a69379 --- /dev/null +++ b/test/test-esp32-p4/autosearch/03_compilation_test.md @@ -0,0 +1,73 @@ +# 03 — Test de compilación: blink ESP32-P4 + +## Setup + +- `arduino-cli 1.4.1` (commit `e39419312`, 2026-01-19) en `C:/Users/000272869/bin/arduino-cli`. +- Core `esp32:esp32 3.3.8` ya instalado (la última disponible al 2026-05-06). +- Sketch: `test/test-esp32-p4/sketches/blink/blink.ino` (toggle GPIO2 + Serial.println, 25 líneas). + +## Comando ejecutado + +```bash +cd test/test-esp32-p4/sketches +arduino-cli compile --fqbn esp32:esp32:esp32p4 blink \ + --output-dir ../../binaries/blink # nota: el flag --output-dir falló, usé el build/ default +``` + +## Output + +``` +Sketch uses 312698 bytes (23%) of program storage space. Maximum is 1310720 bytes. +Global variables use 21980 bytes (6%) of dynamic memory, leaving 305700 bytes for local variables. Maximum is 327680 bytes. +``` + +Exit code: **0**. Tiempo de compilación: ~50 s en frío. + +## Artefactos generados + +`sketches/blink/build/esp32.esp32.esp32p4/`: + +| Archivo | Tamaño | Para qué sirve | +|---|---|---| +| `blink.ino.bin` | 312 880 B | Imagen de la app (sin bootloader). | +| `blink.ino.bootloader.bin` | 21 392 B | Bootloader (offset 0x0000 en flash). | +| `blink.ino.partitions.bin` | 3 072 B | Tabla de particiones (offset 0x8000). | +| `blink.ino.merged.bin` | **4 194 304 B** (4 MB) | Imagen lista para `qemu -drive if=mtd,format=raw`. | +| `blink.ino.elf` | 7 361 896 B | ELF debug; el que abriría GDB. | +| `boot_app0.bin` | 8 192 B | OTA selector. | +| `flash_args` | 172 B | Offsets para `esptool.py write_flash`. | +| `partitions.csv`, `sdkconfig`, `build.options.json`, `blink.ino.map` | misc | metadatos / map de símbolos. | + +## Identificación del ELF + +``` +$ file blink.ino.elf +ELF 32-bit LSB executable, UCB RISC-V, RVC, single-float ABI, version 1 (SYSV), +statically linked, with debug_info, not stripped +``` + +Confirma: +- **RISC-V 32-bit little-endian** → `qemu-system-riscv32`. +- **RVC** (compressed instructions, RV32C extension). +- **single-float ABI** (`ilp32f`) — el chip tiene FPU single-precision. + +## flash_args (offsets para flashing) + +``` +--flash_mode keep --flash_freq keep --flash_size keep +0x0000 blink.ino.bootloader.bin +0x8000 blink.ino.partitions.bin +0xe000 boot_app0.bin +0x10000 blink.ino.bin +``` + +Notar: bootloader en **0x0000** (igual que ESP32-C3), no 0x1000 (como ESP32 Xtensa). El switch `bootloader_offset` en `arduino_cli.py:369` ya hace `0x0000 if _is_esp32c3_board(...) else 0x1000`. Para P4 hay que extender ese helper a "ES_RISCV_BOARD" y meter ahí también `esp32p4*`. + +## Conclusiones + +1. La cadena de toolchain para ESP32-P4 está **lista en arduino-cli sin cambios**. +2. El binary final (`merged.bin` 4 MB) es plug-and-play para QEMU vía `-drive if=mtd,format=raw,file=...` — el mismo patrón que ya usa el `esp_qemu_manager`. +3. Lo único que **falta a nivel toolchain** son ajustes menores en el código de Velxio: + - `arduino_cli.py`: extender `_is_esp32c3_board()` a un `_is_riscv_esp32()` que cubra C3, C6, P4 y H2 para el offset 0x0000. + - `compile.py`: aceptar el FQBN `esp32:esp32:esp32p4` como ESP32-family. +4. **No hay forma de probar el ejecutable** hoy — `qemu-system-riscv32 -M esp32p4` no existe. diff --git a/test/test-esp32-p4/autosearch/04_qemu_backend_path.md b/test/test-esp32-p4/autosearch/04_qemu_backend_path.md new file mode 100644 index 00000000..7734ad0f --- /dev/null +++ b/test/test-esp32-p4/autosearch/04_qemu_backend_path.md @@ -0,0 +1,80 @@ +# 04 — Vía QEMU backend (la realista, pero bloqueada) + +Velxio ya tiene la infraestructura para emular ESP32 vía QEMU. Sumar P4 sería trivial **si la máquina existiera**. + +## Estado actual del soporte QEMU + +| Fork | Última versión revisada | ESP32-P4 | +|---|---|---| +| `espressif/qemu` (oficial) | `esp-develop-9.2.2-20260417` | ❌ no implementado. Carpeta `hw/riscv` solo tiene `esp32c3.c`, `esp32c3_clk.c`, `esp32c3_intmatrix.c`. [Issue #127 abierto desde 2025-05](https://github.com/espressif/qemu/issues/127), label "Status: To Do". | +| `lcgamboa/qemu` (PICSimLab) | `picsimlab-esp32` | ❌ solo ESP32 + C3. README enumera explícitamente esos dos. | +| `Ebiroll/qemu_esp32` | base 9.2 | ❌ ESP32 Xtensa + S2; no menciona P4. | +| `epiclabs-uc/qemu-esp32` | espejo Espressif | ❌ | +| `max1220/qemu-esp32` | base Espressif + patches | ❌ | + +**No existe ningún fork público de QEMU que emule ESP32-P4 al 2026-05-06.** + +## Cuando exista — cambios necesarios en Velxio + +### Backend + +`backend/app/services/esp_qemu_manager.py:41`: +```python +_MACHINE: dict[str, tuple[str, str]] = { + 'esp32': (QEMU_XTENSA, 'esp32'), + 'esp32-s3': (QEMU_XTENSA, 'esp32s3'), + 'esp32-c3': (QEMU_RISCV32, 'esp32c3'), + 'esp32-p4': (QEMU_RISCV32, 'esp32p4'), # ← nuevo +} +``` + +`backend/app/services/arduino_cli.py:212`: +```python +def _is_esp32_riscv_board(self, fqbn: str) -> bool: + """ESP32 RISC-V variants: C3, C6, H2, P4.""" + return any(s in fqbn for s in ('esp32c3', 'esp32c6', 'esp32h2', 'esp32p4')) +``` +y reemplazar la única call a `_is_esp32c3_board(...)` en línea 369 por `_is_esp32_riscv_board(...)`. (Bootloader offset 0x0000 es el mismo para todas las P-cores RISC-V.) + +`backend/app/services/esp32_lib_manager.py:73-76` (mapping a libs PICSimLab): +```python +'esp32-p4': 'esp32p4-picsimlab', # ← cuando el fork lcgamboa lo soporte +``` +Hasta que esto exista, el backend tendría que **rutar P4 al binario QEMU oficial Espressif**, no al `lcgamboa` con bibliotecas PICSimLab. Se pierde Wi-Fi/BLE simulado, pero el chip P4 tampoco tiene radio nativa, así que es coherente. + +### NIC / Wi-Fi + +`esp_qemu_manager.py:213` actualmente hace: +```python +nic_model = 'esp32c3_wifi' if 'c3' in machine else 'esp32_wifi' +``` + +Para P4 esto **no aplica** porque el chip no tiene radio. Wi-Fi en hardware real viene de un ESP32-C6 externo por SDIO. Opciones cuando llegue QEMU: + +1. **Sin Wi-Fi en P4**: forzar `wifi_enabled = False` siempre. Si el sketch llama `WiFi.begin()`, simplemente reportar timeout. Pragmático. +2. **Wi-Fi mock**: interceptar a nivel serial los strings de IDF (`wifi:state: init -> auth`) ya que `wifi_status_parser.py` ya parsea esos. Permitiría UI verde "conectado" sin emular el bus SDIO. Más trabajo, mejor UX. +3. **Bus SDIO emulado al C6**: imposible hoy, complejidad de meses. + +Recomendación: opción **1** al inicio, opción **2** después si hay demanda. + +### Frontend + +`frontend/src/types/board.ts:1`: +```ts +export type BoardKind = + | ... + | 'esp32-p4'; // ← agregar +``` + +`frontend/src/utils/boardPinMapping.ts`: agregar mapping pin-name → GPIO number para los 55 GPIOs del P4 (ver Espressif datasheet §3.4). + +`frontend/src/store/useSimulatorStore.ts`: registrar el board en el factory de boards. + +## Roadmap estimado upstream + +Sin información oficial de Espressif sobre fechas. Patrón histórico: +- ESP32-C3 fue añadido a `espressif/qemu` ~6-8 meses después del lanzamiento del chip. +- ESP32-S3 ~12 meses después. +- ESP32-P4 lleva ~3 años en el mercado y aún sin QEMU. + +**No es razonable esperar una fecha**. Vale la pena suscribirse al [issue #127](https://github.com/espressif/qemu/issues/127) y a las [releases](https://github.com/espressif/qemu/releases). diff --git a/test/test-esp32-p4/autosearch/05_frontend_emulation_path.md b/test/test-esp32-p4/autosearch/05_frontend_emulation_path.md new file mode 100644 index 00000000..526cd576 --- /dev/null +++ b/test/test-esp32-p4/autosearch/05_frontend_emulation_path.md @@ -0,0 +1,61 @@ +# 05 — Vía frontend (browser): por qué no es viable hoy + +El otro patrón de Velxio es ejecutar el emulador **en el browser** (sin backend, sin WebSocket): así corren AVR (`avr8js`) y RP2040 (`rp2040js`). Para ESP32-P4 esta vía está cerrada por falta de un emulador open-source. + +## Opciones evaluadas + +### 1. Emulador JS dedicado (estilo `avr8js` / `rp2040js`) + +**No existe.** Wokwi mantiene `avr8js` y `rp2040js` open-source en GitHub bajo MIT, pero su engine ESP32 (incluido el P4) es **cerrado** y forma parte del producto Wokwi Cloud / Wokwi VS Code. Verificado: + +``` +$ # listado de repos públicos org wokwi en github +avr8js # open +rp2040js # open +esp32p4-hello-world # solo sketch ejemplo, NO engine +esp32p4-mipi-dsi-panel-demo # solo sketch ejemplo +esp32-roms # ROMs reverse-engineered +esp32-test-binaries # firmware de prueba +# NO HAY: esp32js, esp32p4js, esp32-emulator, etc. +``` + +Construir un emulador RV32IMAFC + 55 GPIOs + I²C/SPI/UART/I²S/USB/MIPI-DSI desde cero es **trabajo de años** para una sola persona. Out of scope para este proyecto. + +### 2. Emuladores RISC-V genéricos (rvemu, riscv-rust, TinyEMU) + +| Proyecto | Lenguaje | ISA | ¿Sirve para ESP32-P4? | +|---|---|---|---| +| `d0iasm/rvemu` | Rust + WASM | RV64GC, Sv39, UART/PLIC/CLINT | ❌ apunta a Linux/xv6, no a ESP32 SoC. | +| `takahirox/riscv-rust` | Rust + WASM | RV64IMAFD, Sv39 | ❌ idem. | +| `TinyEMU` (F. Bellard) | C → wasm | RV32IMA, RV64GC | ❌ idem; emula virtio, no ESP32 mem-map. | + +El problema no es el CPU — RV32IMAFC es estándar y cualquiera de estos lo ejecuta — el problema son **los periféricos chip-específicos**: GPIO matrix, IO MUX, RTC, SYSCON, INTERRUPT_CORE, USB OTG, etc. **Sin esos, el firmware se cuelga en el bootloader** intentando configurar reloj y memoria. + +### 3. QEMU compilado a WASM + +Patrón explorado en `test/esp32-emulator/qemu-wasm/Dockerfile` para Xtensa (vía Emscripten). Aplicaría igual al P4 **si `espressif/qemu` tuviera la máquina**, pero como no la tiene, este path está bloqueado por la misma razón que el backend. + +Trade-off: aún cuando esté listo, QEMU-WASM: +- pesa ~30-40 MB (chunk lazy-loaded). +- es ~5-10× más lento que QEMU nativo en backend. +- no tiene WebSocket overhead. + +Conclusión: **prefiere backend QEMU** sobre QEMU-WASM para ESP32 boards en general. Coincide con la decisión que ya tomó Velxio para C3/S3. + +### 4. Espressif IDF Component Manager + QEMU oficial reutilizado en cliente + +Imposible: el QEMU oficial es ELF/EXE para Linux/Mac/Windows, no WASM. Habría que recompilarlo (vuelve a opción 3). + +## Por qué AVR y RP2040 sí están en frontend + +- **AVR**: ISA chiquita (~131 instrucciones, 8-bit). avr8js son ~5 K líneas TS. +- **RP2040**: ARM Cortex-M0+ con set reducido. rp2040js son ~10 K líneas TS y aprovecha que el RP2040 es bien documentado y open silicon. +- **ESP32-P4**: SoC de **última generación** con dual-core, FPU, AI extensions, MMU, cache, MIPI… al menos un orden de magnitud más complejo. Sin la documentación interna (que Espressif solo da parcialmente), el reverse-engineering completo es prohibitivo. + +## Veredicto + +La vía frontend para ESP32-P4 está **descartada** salvo dos eventos improbables a corto plazo: +- Wokwi libera su engine ESP32 (no hay señales de eso). +- Espressif publica un emulador WASM oficial. + +La única vía realista es **backend QEMU cuando exista la máquina** — ver [`04_qemu_backend_path.md`](04_qemu_backend_path.md). diff --git a/test/test-esp32-p4/autosearch/06_recommendations.md b/test/test-esp32-p4/autosearch/06_recommendations.md new file mode 100644 index 00000000..f173abb1 --- /dev/null +++ b/test/test-esp32-p4/autosearch/06_recommendations.md @@ -0,0 +1,61 @@ +# 06 — Recomendaciones / plan accionable + +## Decisión propuesta + +**No agregar ESP32-P4 como board emulable hoy.** Sumarlo en estado "compilable, no emulable" tiene un valor marginal (el usuario ve el ELF generado, pero al pulsar Run no pasa nada útil) y crea expectativa que no se puede cumplir. + +Sin embargo, **toda la plomería de toolchain** se puede dejar lista hoy con muy poco esfuerzo, de modo que el día que `espressif/qemu` mergee la máquina P4, sumar el board sea cuestión de un PR de ~50 líneas. + +## Plan en 3 fases + +### Fase A — Hoy (preparación, sin exponer al usuario) + +Esfuerzo: ~2 h. Riesgo: bajo. **No** agrega un board nuevo en el frontend. + +1. **Refactor mínimo en `arduino_cli.py`**: renombrar `_is_esp32c3_board` → `_is_esp32_riscv_board` y extender la lista a `esp32c3, esp32c6, esp32h2, esp32p4`. Misma lógica de `bootloader_offset = 0x0000`. ~10 líneas. +2. **Subscribirse al [issue #127 de espressif/qemu](https://github.com/espressif/qemu/issues/127)** para enterarse cuando aterrice la máquina P4. +3. **Mantener este folder `test/test-esp32-p4/`** como referencia viva — actualizar `01_findings.md` cada vez que haya un release de `espressif/qemu`. + +### Fase B — Cuando QEMU soporte ESP32-P4 + +Esfuerzo: ~1-2 días. Riesgo: medio (depende de qué peripherals emule realmente la máquina). + +1. **Backend (`esp_qemu_manager.py`)**: + - Agregar `'esp32-p4': (QEMU_RISCV32, 'esp32p4')` al `_MACHINE` dict. + - Forzar `wifi_enabled = False` para P4 (chip sin radio nativa) — devolver warning explícito si el usuario lo activa. +2. **Frontend (`types/board.ts`)**: + - Agregar `'esp32-p4'` a `BoardKind`. + - Agregar a `BOARD_KIND_LABELS` con label "ESP32-P4 Dev Module". + - Agregar a `BOARD_SUPPORTS_MICROPYTHON` (MicroPython tiene puerto P4 desde mediados 2025). +3. **Pin mapping (`utils/boardPinMapping.ts`)**: + - Mapear los 55 GPIOs según pinout del Dev Module Espressif. Patrón idéntico al ESP32-S3. +4. **Componente visual**: + - SVG nuevo en `components-wokwi/` (no hay element open en `wokwi-elements`). Alternativa de bajo esfuerzo: reutilizar el SVG del ESP32-S3 con renombrado de pines, hasta tener un dibujo propio. +5. **Smoke test**: `test/test-esp32-p4/scripts/smoke.sh` que (a) compila blink, (b) lanza `qemu-system-riscv32 -M esp32p4 -drive ...`, (c) verifica que aparece "ESP32-P4 blink starting" en el TCP serial. +6. **Tests backend**: agregar caso ESP32-P4 a `test/esp32/test_esp32_integration.py`. + +### Fase C — Wi-Fi mock (opcional, cuando haya demanda real) + +Cuando un usuario reporte que quiere usar `WiFi.h` con ESP32-P4, implementar mock por parsing del UART (mismo patrón que `wifi_status_parser.py` ya usa para C3). El bus SDIO al C6 emulado real es prohibitivo y se puede ignorar. + +## Lo que NO hacer + +- ❌ No empezar a portar `rp2040js` a "esp32p4js". Es un proyecto de años y duplica esfuerzo de Wokwi/Espressif. +- ❌ No mergear el board en producción sin el QEMU operacional. Da una mala primera impresión. +- ❌ No comprometerse con Wi-Fi/BLE para este chip. La radio externa C6 es una bestia distinta. +- ❌ No usar QEMU-WASM para P4 mientras el backend QEMU funcione bien para los otros ESP32. Costo (~40 MB WASM extra) > beneficio. + +## Métrica de éxito + +Cuando se ejecute Fase B, el criterio de aceptación es: +- `arduino-cli compile --fqbn esp32:esp32:esp32p4 blink` produce ELF (ya OK). +- En Velxio, seleccionar board "ESP32-P4 Dev Module" + Run reproduce el LED parpadeando + Serial Monitor muestra "HIGH/LOW" cada 500 ms. +- Smoke test CI verde. + +## Cómo monitorear el bloqueante + +- GitHub: watch [espressif/qemu releases](https://github.com/espressif/qemu/releases). +- Issue principal: [#127](https://github.com/espressif/qemu/issues/127). +- Mirror: [esp-toolchain-docs/qemu](https://github.com/espressif/esp-toolchain-docs/tree/main/qemu). + +Cuando aparezca `hw/riscv/esp32p4.c` en `esp-develop`, activar Fase B. diff --git a/test/test-esp32-p4/scripts/compile.sh b/test/test-esp32-p4/scripts/compile.sh new file mode 100644 index 00000000..d7f2a9d0 --- /dev/null +++ b/test/test-esp32-p4/scripts/compile.sh @@ -0,0 +1,18 @@ +#!/usr/bin/env bash +# Compile the blink sketch for ESP32-P4 with arduino-cli. +# Reproduces the test documented in autosearch/03_compilation_test.md. +set -euo pipefail + +HERE="$(cd "$(dirname "$0")" && pwd)" +ROOT="$HERE/.." +SKETCH="$ROOT/sketches/blink" + +echo "[+] Compiling $SKETCH for esp32:esp32:esp32p4" +arduino-cli compile --fqbn esp32:esp32:esp32p4 "$SKETCH" + +BUILD="$SKETCH/build/esp32.esp32.esp32p4" +echo "[+] Output:" +ls -la "$BUILD" +echo +echo "[+] ELF arch:" +file "$BUILD/blink.ino.elf" diff --git a/test/test-esp32-p4/scripts/smoke_qemu.sh b/test/test-esp32-p4/scripts/smoke_qemu.sh new file mode 100644 index 00000000..e9ecaa44 --- /dev/null +++ b/test/test-esp32-p4/scripts/smoke_qemu.sh @@ -0,0 +1,44 @@ +#!/usr/bin/env bash +# Smoke test: run the merged blink binary in qemu-system-riscv32 -M esp32p4. +# +# REQUIREMENTS — none of these is true at 2026-05-06: +# 1. Espressif QEMU fork includes -M esp32p4 (see issue #127, status: To Do). +# 2. qemu-system-riscv32 binary is in PATH. +# +# This script will FAIL today. It exists as a reference for Phase B +# (see autosearch/06_recommendations.md). Re-evaluate when espressif/qemu +# adds hw/riscv/esp32p4.c to esp-develop. +set -euo pipefail + +HERE="$(cd "$(dirname "$0")" && pwd)" +ROOT="$HERE/.." +MERGED="$ROOT/sketches/blink/build/esp32.esp32.esp32p4/blink.ino.merged.bin" + +if [ ! -f "$MERGED" ]; then + echo "[!] $MERGED not found — run scripts/compile.sh first." + exit 1 +fi + +QEMU_BIN="${QEMU_RISCV32_BINARY:-qemu-system-riscv32}" +if ! command -v "$QEMU_BIN" >/dev/null; then + echo "[!] $QEMU_BIN not found in PATH." + echo " Install Espressif QEMU fork: https://github.com/espressif/qemu/releases" + exit 1 +fi + +echo "[+] Available machines:" +"$QEMU_BIN" -M help | grep -i esp || echo " (no ESP32 machines listed)" +echo + +if ! "$QEMU_BIN" -M help | grep -q esp32p4; then + echo "[!] -M esp32p4 not supported by this QEMU build." + echo " Track: https://github.com/espressif/qemu/issues/127" + exit 2 +fi + +echo "[+] Booting $MERGED in QEMU esp32p4 (Ctrl-A X to quit)..." +"$QEMU_BIN" \ + -nographic \ + -M esp32p4 \ + -drive "file=$MERGED,if=mtd,format=raw" \ + -serial mon:stdio diff --git a/test/test-esp32-p4/sketches/blink/blink.ino b/test/test-esp32-p4/sketches/blink/blink.ino new file mode 100644 index 00000000..b409168b --- /dev/null +++ b/test/test-esp32-p4/sketches/blink/blink.ino @@ -0,0 +1,19 @@ +// Minimal blink sketch for ESP32-P4 +// Toggles GPIO2 every 500 ms. + +#define LED_PIN 2 + +void setup() { + Serial.begin(115200); + pinMode(LED_PIN, OUTPUT); + Serial.println("ESP32-P4 blink starting"); +} + +void loop() { + digitalWrite(LED_PIN, HIGH); + Serial.println("HIGH"); + delay(500); + digitalWrite(LED_PIN, LOW); + Serial.println("LOW"); + delay(500); +}