This is a Rust Slint Workshop template supporting multiple ESP32-S3 boards with both std (ESP-IDF) and no_std (bare-metal) implementations.
slint-esp-workshop/
├── README.md
├── Cargo.toml (workspace)
├── ui/ # Shared Slint UI files
├── model/ # Shared model code (no_std compatible)
├── winit/ # Desktop implementation (winit)
├── esp32/ # ESP32 implementations
│ ├── std/ # Standard library implementations (ESP-IDF)
│ │ ├── esp32-s3-box-3/ # ESP32-S3-BOX-3 std implementation
│ │ ├── esope-sld-c-w-s3/ # ESoPE board std implementation (planned)
│ │ ├── m5stack-cores3/ # M5Stack CoreS3 std implementation (planned)
│ │ └── esp32-s3-lcd-ev-board/ # LCD-EV board std implementation (planned)
│ └── no_std/ # No standard library implementations (bare-metal)
│ ├── esp32-s3-box-3/ # ESP32-S3-BOX-3 no_std implementation
│ ├── esope-sld-c-w-s3/ # ESoPE board no_std implementation
│ ├── m5stack-cores3/ # M5Stack CoreS3 no_std implementation
│ └── esp32-s3-lcd-ev-board/ # LCD-EV board no_std implementation (planned)
├── wasm/ # WebAssembly implementation
└── android/ # Android implementation
- ESP32-S3-BOX-3 (std + no_std)
- ESoPE-SLD-C-W-S3 (no_std)
- M5Stack-CoreS3 (no_std)
- ESP32-S3-LCD-EV-BOARD
Choose your preferred implementation approach:
# ESP32-S3-BOX-3 (no_std)
cd esp32/no_std/esp32-s3-box-3
cargo run --release
# ESoPE board (no_std)
cd esp32/no_std/esope-sld-c-w-s3
cargo run --release# ESP32-S3-BOX-3 (std)
cd esp32/std/esp32-s3-box-3
cargo run --releasePros:
- ✅ Much simpler setup - No C/C++ toolchain required
- ✅ Pure Rust - No ESP-IDF complexity
- ✅ Smaller binary size and memory footprint
- ✅ Better performance and lower latency
- ✅ Direct hardware control with esp-hal
- ✅ Faster compilation times
- ✅ More predictable behavior
- ✅ esp-alloc provides heap allocation when needed
- ✅ Highly portable code - Works across different platforms
- ✅ No_std ecosystem designed for embedded/portable use
Cons:
- ❌ Some std-only crates not available (though embedded alternatives exist)
Pros:
- ✅ Familiar Rust std library
- ✅ Access to std-only crates
- ✅ Built-in WiFi/networking stack
Cons:
- ❌ Complex setup - Requires full C/C++ ESP-IDF toolchain
- ❌ Much more complex - ESP-IDF brings C/C++ complications
- ❌ Larger binary size
- ❌ Higher memory usage
- ❌ Slower compilation
- ❌ Less direct hardware control
- ❌ Platform-locked code - Hard to port to other embedded platforms
Recommendation: Start with no_std for a simpler, pure Rust experience with portable code. Only use std if you specifically need existing ESP-IDF C++ components.
For the std (ESP-IDF) implementations, you must use ESP-IDF v5.2. This is a requirement for proper compilation and linking with the Rust code.
- Rust toolchain (minimum version 1.80)
- An IDE, such as VSCode, with the Slint extension
To use this template, make sure Rust and the necessary components are installed for no_std ESP32-S3 development:
rustup target add xtensa-esp32s3-none-elf
cargo install espflash Install the Slint extension from the extensions marketplace.
- No standard library (no_std) - Optimized for embedded systems
- Multi-board support - Works with multiple ESP32-S3 development boards
- Slint UI framework - Rich graphics and touch interface
- WiFi ready - Stub implementation ready for WiFi functionality
- Embassy async runtime - Modern async/await support for embedded
This workshop uses a no_std bare-metal implementation, which means:
- No standard library - Uses
coreandalloccrates only - No heap allocation by default - Uses PSRAM for dynamic allocation
- Direct hardware access - Through esp-hal crate
- No ldproxy required - Direct compilation to embedded target
- Optimized for embedded - Smaller binary size and better performance
- esp-hal 1.0.0-beta.1 - Hardware abstraction layer for ESP32-S3
- embassy - Async runtime for embedded systems
- slint - UI framework with no_std support
- esp-alloc - Memory allocator for ESP32 with PSRAM support
The project uses:
- Target:
xtensa-esp32s3-none-elf(bare-metal, no std) - Build std:
["alloc", "core"]for no_std with allocation - Custom linker scripts - For proper memory layout
- DMA and PSRAM - For framebuffer and graphics performance
Assuming you have installed Rust (minimum version 1.80), please install the following packages via apt:
sudo apt install make gcc g++ libssl-dev pkg-config libudev-dev python3 python3-pip python3-venv
sudo apt install wget flex bison gperf cmake ninja-build ccache libffi-dev dfu-util libusb-1.0-0 usbutilscargo install espup --locked # ESP toolchain setup
cargo install espflash # Flashing toolespup install # Installs the toolchain. Only has to be done once.
. ${HOME}/export-esp.sh # This step has to be done for each shell sessionChange directory to the esp32 folder and build the project:
cd esp32
cargo build --releaseFlash the application to the device:
cargo espflash --releaseIf not done already, open a PowerShell as administrator and install WSL:
wsl --installOpen a new WSL shell and do the following steps:
sudo apt update && sudo apt upgrade -ycurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shsudo apt install gcc g++ libssl-dev pkg-config libudev-dev make flex bison gperf cmake ccache ninja-build
sudo apt install git wget libxkbcommon-x11-dev python3 python3-pip python3-venv python3.12-venv libffi-dev dfu-util libusb-1.0-0 usbutilsInstall these dependencies required to set up the ESP toolchain:
cargo install espup # ESP toolchain setup
cargo install espflash # Flashing tool
cargo install cargo-generate # Required to actually check out the templateChange the directory to the root of this repository. You need to set up the ESP toolchain and initialize the environment:
espup install # Installs the toolchain. Only has to be done once.
. ${HOME}/export-esp.sh # This step has to be done for each shell sessionYou should now be able to build the project with cargo build --release.
- Download the installer at: https://github.com/dorssel/usbipd-win/releases/
- Assuming your ESP32 is connected to your computer, open a PowerShell as administrator and list the USB devices:
usbipd listIf everything is correctly connected and installed, a list of the something similar on the console:
2-9 303a:1001 USB Serial Device (COM8), USB JTAG/serial debug unit Not sharedThe id 2-9 on the left is the bus number. It might be different on your machine.
First, bind the bus to the usbipd service:
usbipd bind --busid 2-9 # This only has to be done onceAfter that, attach the bus to WSL:
usbipd attach --wsl --busid 2-9 # This has to be done for each WSL session and each time the device is disconnectedIn your WSL shell, test with lusb if you can see the ESP32 in the list.
The list in the console output must contain:
Bus 001 Device 003: ID 303a:1001 Espressif USB JTAG/serial debug unitNow, your device can be flashed and you can run your application via cargo espflash --release.
The workshop application includes:
- Tabbed Interface - WiFi and About tabs
- WiFi Tab - Shows network list with refresh functionality (stub implementation)
- About Tab - Displays Slint framework information
- Touch Support - Works with capacitive touch displays
- Responsive Design - Adapts to different screen sizes
If you encounter I2C(AcknowledgeCheckFailed(Address)) errors with the board:
- Switch to ESP32-S3-BOX-3 (default) - This board doesn't require EEPROM
- Check hardware connections - Ensure I2C pins are properly connected
- Verify EEPROM address - The board might use a different I2C address
- Missing target: Run
rustup target add xtensa-esp32s3-none-elf - Linker errors: Make sure ESP toolchain is properly installed with
espup install - Version conflicts: Clean build with
cargo cleanand rebuild
- Check USB connection - Ensure the board is connected and in download mode
- Driver issues - Install proper USB drivers for your board
- Permission issues - On Linux, you might need to add your user to the
dialoutgroup
This workshop is ready for extending with:
- Real WiFi scanning - Replace stub implementation with esp-wifi
- Network connectivity - Add TCP/UDP networking
- IoT features - MQTT, HTTP clients, etc.
- Advanced UI - More complex Slint components
- Sensors - Add sensor data display