This project runs R2P2 (Ruby Rapid Portable Platform), a PicoRuby shell, on ESP32.
If this is your first time running PicoRuby on an ESP32, you can get up and running quickly with just a few steps!
- Prepare your device and connect it to your PC via USB (see Supported Devices)
- Visit the R2P2-ESP32 Web Installer (Chrome, Edge, or Opera required)
- Select your target and VM, then click "Connect and Flash"
- After flashing, open the R2P2 Web Terminal and click "Connect" to access the
picoruby-shell
Once the picoruby-shell prompt appears, type irb to start a REPL directly on your device.
$> irb
irb> 1 + 2
=> 3
irb> words = ["Hello", "PicoRuby", "!"]
=> ["Hello", "PicoRuby", "!"]
irb> words.join(" ")
=> "Hello PicoRuby !"
irb>
In the "File Editor" panel of the R2P2 Web Terminal, write a program like this:
words = ["Hello", "PicoRuby", "!"]
puts words.join(" ")Change the path from /home/app.rb to /home/hello.rb and click "Upload" to write the file to your device.
You can then run it with:
$> ls
hello.rb
$> ./hello.rb
Hello PicoRuby !
$>
For available classes and features, see PicoRuby.org.
picoruby-shell comes with a variety of built-in commands:
$> echo 'Hello!'
Hello!
$> cat hello.rb
words = ["Hello", "PicoRuby", "!"]
puts words.join(" ")
$> mkdir 'tmp'
$> cd 'tmp'
$> pwd
/home/tmp
$> reboot
See here for the full list of available commands.
You will need to set up a development environment if you want to:
- Add or remove mrbgems
- Write and include your own custom mrbgem
- Contribute to PicoRuby or R2P2-ESP32
- Expand heap space or enable PSRAM support
- Meet any other requirement not covered by the pre-built firmware images
Set up your development environment using ESP-IDF by referring to this page. The build has been verified with ESP-IDF v5.5.
Clone the repository with all submodules:
$ git clone --recursive https://github.com/picoruby/R2P2-ESP32.gitSome hardware variants require additional configuration via the SDKCONFIG_DEFAULTS environment variable.
Fragment files for each option are provided under sdkconfigs/.
You can combine them as needed by appending fragment file paths separated by semicolons.
Here are some examples:
When using USB console (boards without an external USB-to-UART chip):
$ export SDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfigs/usb_console"When using USB console with SPIRAM:
$ export SDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfigs/usb_console;sdkconfigs/spiram"Set the environment variable before running rake setup_* and rake build.
If you change SDKCONFIG_DEFAULTS, delete the sdkconfig file and rebuild from scratch.
Run the setup task for your target (first time only):
$ cd R2P2-ESP32
# Activate ESP-IDF (replace x with your patch version, e.g. 4)
$ source ~/.espressif/tools/activate_idf_v5.5.x.sh
$ export PATH="$IDF_PATH/tools:$PATH"After activation, add Ruby to PATH using your version manager:
# mise:
$ mise use ruby@4.0.5
# asdf:
$ asdf local ruby 4.0.5
# rbenv:
$ rbenv local 4.0.5Note: The setup task builds some host-side tools with the host (non-cross) toolchain. It is detected automatically even while ESP-IDF's cross toolchains are on PATH. If the detection picks a wrong compiler or archiver, override it with the
HOST_CC/HOST_ARenvironment variables.
Tip: You can manage the above environment variables in a
.envrcfile using direnv, so they are applied automatically whenever you enter the project directory.
source ~/.espressif/tools/activate_idf_v5.5.4.sh
PATH_add "$IDF_PATH/tools"
# Setup (first time only)
$ rake setup_esp32 # if you use esp32
$ rake setup_esp32c3 # if you use esp32c3
$ rake setup_esp32c6 # if you use esp32c6
$ rake setup_esp32h2 # if you use esp32h2
$ rake setup_esp32p4 # if you use esp32p4
$ rake setup_esp32s3 # if you use esp32s3
# Build
$ rake buildPicoRuby currently supports two VMs. Run the build task for the one you want to use:
# PicoRuby (VM: mruby)
rake picoruby:build
# FemtoRuby (VM: mruby/c)
rake femtoruby:buildSee Supported Devices for which VMs are available for each device.
WiFi native code (Network::WiFi / ESP32::WiFi, and by extension picoruby-socket's
TCPServer/TCPSocket over WiFi) is not compiled in by default. To enable it, set the
USE_WIFI environment variable before building:
$ export USE_WIFI=1
$ rake buildThis is required, for example, to use picoruby-debug's DAP remote debugging over WiFi.
Note:
USE_WIFIis only read while CMake configures the project, not on every build. If you already ranrake setup_*orrake buildwithoutUSE_WIFIset, a plainUSE_WIFI=1 rake buildwill not pick it up and can fail with linker errors such asundefined reference to 'ESP32_WIFI_init'. Force a reconfigure first:$ export USE_WIFI=1 $ idf.py reconfigure $ rake buildAlternatively, run
rake setup_*again withUSE_WIFI=1already exported.
Flash the built image to your device:
$ rake flashOpen a serial terminal to connect to your device:
$ rake monitorR2P2-ESP32 can be run under QEMU targeting ESP32-S3, without any real hardware. This uses ESP-IDF's built-in idf.py qemu support and the qemu-xtensa tool package (idf_tools.py install qemu-xtensa).
Set up a separate build directory (build-qemu) once, targeting ESP32-S3 with a UART console (QEMU does not emulate the USB Serial/JTAG console):
$ rake setup_qemuThen run it with the VM of your choice:
$ rake femtoruby:qemu # VM: mruby/c
$ rake picoruby:qemu # VM: mruby
$ rake qemu # whichever VM is currently configured in build-qemu (defaults to femtoruby/mrubyc)This drops you into the picoruby-shell prompt over the emulated UART. Use Ctrl-A X to quit QEMU (-nographic mode).
Known QEMU limitations:
- USB Serial/JTAG console is not emulated.
rake setup_qemubuilds withsdkconfigs/qemu(UART console) regardless of your usualSDKCONFIG_DEFAULTS, since a USB Serial/JTAG console build hangs forever waiting for a host connection that QEMU never provides. - ADC/SENS peripherals are not emulated, so the ADC hardware self-calibration that normally runs before
app_mainspins forever.rake qemuworks around this by burningBLK_VERSION_MAJOR=1into the QEMU eFuse image the first time it runs, which makes calibration read from (zeroed) eFuse data instead of touching the hardware. ADC readings under QEMU are therefore not meaningful. - PSRAM is capped at 8MB (
--qemu-extra-args='-m 8M') even though the real hardware may have more. With the default 32MB, QEMU cannot map the full PSRAM into the virtual address space, and mounting thestorage(littlefs) partition then crashes withesp_mmu_map: no such vaddr range. USE_WIFIbuilds still compile, but QEMU only emulates an Ethernet MAC (open_eth), not real WiFi hardware, soNetwork::WiFi/ESP32::WiFiwon't work under QEMU.
The following devices have been confirmed to work:
| Device | Target | VM | USB Console | SPIRAM |
|---|---|---|---|---|
| ESP32-DevKitC | ESP32 | FemtoRuby (mruby/c) | No | No |
| ATOM Matrix | ESP32 | FemtoRuby (mruby/c) | No | No |
| M5Stamp C3 Mate | ESP32-C3 | FemtoRuby (mruby/c) | No | No |
| ESPr® Developer S3 Type-C | ESP32-S3 | FemtoRuby (mruby/c), PicoRuby (mruby) | No | Yes |
| ATOMS3 Lite | ESP32-S3 | FemtoRuby (mruby/c), PicoRuby (mruby) | Yes | No |
| M5Stack CoreS3 | ESP32-S3 | FemtoRuby (mruby/c), PicoRuby (mruby) | Yes | Yes |
R2P2-ESP32 is released under the MIT License.