Run a prebuilt firmware

Run a Pico SDK or ESP-IDF build on the Pico, the ESP32 or the ESP32-S3, the way Wokwi runs the file wokwi.toml names.

Mokxi builds Arduino sketches itself when you press Run. A program written for the Raspberry Pi Pico SDK (C or C++ with pico/stdlib.h) or for ESP-IDF (app_main), or in Rust with esp-hal or esp-idf-hal, is not built here: you build it on your own computer and give Mokxi the file the build made. The board then boots it exactly as the real one does after the file is written to it.

Upload a firmware

  1. Put a Raspberry Pi Pico (a Pico W or an Arduino Nano RP2040 Connect works too), or an ESP32 or ESP32-S3 board, on the canvas and click it.
  2. In its properties, open program and choose Upload firmware.
  3. Pick the file your build made, and press Run.

Which files each board takes:

Board Files How it boots
Pico, Pico W, Nano RP2040 Connect .uf2, .elf through the boot ROM and the image's own second stage, as after copying the file onto the board's drive
ESP32 DevKit V1, DevKitC, LOLIN32 Lite .bin, .elf as after idf.py flash: the application at 0x10000, or a merged image where the build put it
ESP32-S3 DevKitC-1, XIAO ESP32-S3, Nano ESP32 .bin, .elf the same

On a Pico the Serial Monitor shows both of the Pico SDK's serial outputs: UART0 on GP0 and GP1 at 115200 baud (pico_enable_stdio_uart) and the USB serial port (pico_enable_stdio_usb). On an ESP32 or ESP32-S3 it is UART0, the port the chip logs to. What you type goes to the board either way.

A .elf is kept as the image the board boots, without its debug information, so a big .elf usually fits. The kept file can be 2 MB at most. A file built for another chip is refused with a sentence naming the chip it was built for.

Build one on your computer

Install the Pico SDK the way Raspberry Pi's Getting started with the Raspberry Pi Pico guide says, or use the Raspberry Pi Pico extension for VS Code, which sets up the SDK and the compiler for you. Then, in your project's folder:

mkdir build
cd build
cmake .. -DPICO_BOARD=pico
make

The build leaves <your program>.uf2 and <your program>.elf in build/. Upload either one. After you change the code, build again and upload the new file: Mokxi runs the file you gave it, not the code in the editor.

For an ESP32 or ESP32-S3, install ESP-IDF the way Espressif's Get Started guide says, then in your project's folder:

idf.py set-target esp32
idf.py build

That leaves build/<your project>.bin and build/<your project>.elf. Upload either one. A merged image (esptool merge-bin) works too, and so does a Rust build: cargo build --release with esp-hal (bare metal) or esp-idf-hal, then the ELF from target/, or the .bin espflash save-image writes.

From Wokwi

A Wokwi for VS Code project names its build in wokwi.toml (firmware = 'build/blink.uf2' for a Pico, firmware = 'build/flasher_args.json' for ESP-IDF). Import the project with that file in the upload (a zip of the whole folder, build/ included, is easiest) and the board runs it: the import report says which file it took. Without the file, the report says which one to add.

What runs, and what does not yet

On the Pico, the boot ROM, flash, clocks, timer, UART, GPIO, PWM, ADC, I2C, SPI, DMA, PIO, USB and watchdog are all simulated, so most Pico SDK examples run as they are, WS2812 LEDs through ws2812.pio included. On a Pico W the CYW43439 is modeled as the official MicroPython and CircuitPython builds drive it through cyw43-driver, the driver pico_cyw43_arch links, and it joins Mokxi's simulated network; Bluetooth, the access point mode's clients, power save and TLS are not simulated. What does not run:

  • The second core. multicore_launch_core1 stops the board.
  • The system clock is always 125 MHz, whatever set_sys_clock_khz asks.

On the ESP32 and ESP32-S3, the firmware boots on a model of the whole chip, both cores included: the mask ROM, flash behind the cache, the timers, the interrupt matrix, GPIO, LEDC, RMT, I2C, the SPI masters, the UARTs and ADC1. ESP-IDF's own hello_world, blink, GPIO, LEDC and FreeRTOS examples run, and so do Rust builds. What does not:

  • Wi-Fi and Bluetooth. Their drivers are Espressif's closed libraries driving a radio with no public registers, so a firmware that starts either one stops at the radio with a line in the Serial Monitor saying so. (An Arduino sketch's Wi-Fi does work: Mokxi builds it against its own runtime.)
  • A peripheral the model does not have (I2S, the pulse counter, motor control PWM, TWAI, SD/MMC, the crypto accelerators) stops the board with a line naming it, rather than running on registers that only remember what was written.
  • Light and deep sleep, and PSRAM, are not simulated.

The ESP32-C3 and ESP32-C6 boards do not run an ESP-IDF build yet: they run Arduino sketches, built here.