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) <noreply@anthropic.com>
This commit is contained in:
parent
694a2f4073
commit
0fdbeffda5
|
|
@ -0,0 +1,2 @@
|
|||
sketches/*/build/
|
||||
binaries/
|
||||
|
|
@ -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
|
||||
```
|
||||
|
|
@ -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)
|
||||
|
|
@ -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).
|
||||
|
|
@ -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.
|
||||
|
|
@ -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).
|
||||
|
|
@ -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).
|
||||
|
|
@ -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.
|
||||
|
|
@ -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"
|
||||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
}
|
||||
Loading…
Reference in New Issue