Skip to content

Commit 1b5ffc1

Browse files
committed
add Slint workshop
1 parent dee775e commit 1b5ffc1

File tree

7 files changed

+826
-0
lines changed

7 files changed

+826
-0
lines changed
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
---
2+
title: "Slint with Rust on ESP32 Workshop - no_std and std"
3+
date: 2025-06-03T00:00:00+01:00
4+
tags: ["Workshop", "Slint", "Rust", "ESP32", "no_std", "std", "Embedded UI"]
5+
---
6+
7+
Welcome to the **Slint with Rust on ESP32** workshop!
8+
9+
## About this workshop
10+
11+
This hands-on workshop is designed to introduce embedded developers to designing modern graphical user interfaces using the [Slint UI Toolkit](https://slint.dev) in Rust for the ESP32 platform. The workshop supports **both `no_std` (bare-metal) and `std` (ESP-IDF) approaches**, with **`no_std` as the primary and recommended path** due to its simplicity, better performance, and official Espressif support.
12+
13+
Unlike traditional workflows that start directly on embedded hardware, this training emphasizes a **desktop-first** approach: you begin by developing and testing the UI on your desktop, then port the same code to an embedded platform. This is made possible thanks to Slint's cross-platform design and support for Rust in both `no_std` and `std` environments.
14+
15+
While Slint supports other languages such as C++ or Python, this workshop is focused entirely on **pure Rust**.
16+
17+
> Although the examples run on the ESP32-S3, the concepts can be ported to other [ESP32 targets with display capability](https://github.com/espressif/esp-bsp).
18+
19+
## Choosing Your Development Approach
20+
21+
This workshop supports both development approaches with **`no_std` (bare-metal) as the primary recommendation**:
22+
23+
### `no_std` (Bare-Metal) - **RECOMMENDED**
24+
25+
**Why choose `no_std`:**
26+
-**Much simpler setup** - No C/C++ toolchain required
27+
-**Pure Rust** - No ESP-IDF complexity
28+
-**Official Espressif support** - First-class citizen in esp-hal ecosystem
29+
- ✅ Smaller binary size and memory footprint
30+
- ✅ Better performance and lower latency
31+
- ✅ Direct hardware control with esp-hal
32+
- ✅ Faster compilation times
33+
- ✅ More predictable behavior
34+
-**Highly portable code** - Works across different embedded platforms
35+
36+
**When to choose `no_std`:** Recommended for most embedded projects, especially when you want a pure Rust experience.
37+
38+
### `std` (ESP-IDF) - Alternative Approach
39+
40+
**When to choose `std`:**
41+
- You specifically need existing ESP-IDF C/C++ components
42+
- You have a large existing C/C++ codebase to integrate
43+
- You require std-only crates that don't have no_std alternatives
44+
45+
**Considerations with `std`:**
46+
-**Complex setup** - Requires full C/C++ ESP-IDF toolchain
47+
- ❌ Larger binary size and higher memory usage
48+
- ❌ Slower compilation times
49+
- ❌ Platform-specific code - harder to port to other embedded platforms
50+
51+
**Default Choice:** Start with **`no_std`** for the best embedded Rust experience. Only switch to `std` if you have specific requirements that necessitate it.
52+
53+
## Agenda
54+
55+
With the prerequisites in place, follow the assignments in order:
56+
57+
- [Assignment 1: Environment Setup](assignment-1) — install Rust toolchain, dependencies, and tools for Slint and ESP32.
58+
- [Assignment 2: Run GUI on Desktop](assignment-2) — create a simple two-tab UI with the Slint logo and a placeholder for Wi-Fi list.
59+
- [Assignment 3: Run GUI on ESP32-S3](assignment-3) — port the same app to embedded hardware such as M5Stack CoreS3, ESoPe Board (SLD_C_W_S3), ESP32-S3-BOX-3, or ESP32-S3-LCD-EV-Board.
60+
- [Assignment 4: Add Wi-Fi list on Desktop](assignment-4) — populate the placeholder list with available networks using the OS backend.
61+
- [Assignment 5: Add Wi-Fi scan on ESP32](assignment-5) — replace the desktop data source with live Wi-Fi scan results from the ESP32.
62+
- [Assignment 6: Explore more Slint examples](assignment-6) — interactive demos and links to advanced usage patterns.
63+
64+
## Prerequisites
65+
66+
**Hardware:**
67+
68+
- **[M5Stack CoreS3](https://shop.m5stack.com/products/m5stack-cores3-esp32s3-lotdevelopment-kit)** (recommended - touchscreen, speakers, microphone)
69+
- [ESoPe Board SLD_C_W_S3 with Schukat Smartwin display-concept](https://esope.de) (RGB interface)
70+
- Alternative boards: [ESP32-S3-BOX-3](https://github.com/espressif/esp-bsp/tree/master/bsp/esp32_s3_box_3), [ESP32-S3-LCD-EV-Board](https://github.com/espressif/esp-bsp/tree/master/bsp/esp32_s3_lcd_ev_board)
71+
- USB-C cable for M5Stack CoreS3 and ESP32-S3-BOX-3, or USB micro cable with [ESP-Prog](https://docs.espressif.com/projects/esp-iot-solution/en/latest/hw-reference/ESP-Prog_guide.html) for ESoPe board
72+
73+
**Software:**
74+
75+
- [Rust toolchain](https://rustup.rs) (stable channel is sufficient)
76+
- [`espup`](https://github.com/esp-rs/espup) to install and configure `esp-rust` toolchain (**recommended method**)
77+
- `espflash` for flashing firmware
78+
- `cargo-generate` for creating project templates
79+
- [JetBrains RustRover](https://www.jetbrains.com/rust/) or [CLion](https://www.jetbrains.com/clion/)**recommended IDEs**, available free for students and open source projects
80+
- Alternatively, VS Code with Rust Analyzer, or any terminal-based Rust development setup
81+
82+
JetBrains IDEs (CLion or RustRover) are highly recommended and provide excellent Rust tooling out of the box. These tools are available free of charge for students and open source contributors.
83+
84+
Follow [Slint Embedded Setup Instructions](https://docs.slint.dev/latest/docs/slint/) for more details.
85+
86+
## Time Estimate
87+
88+
{{< alert icon="mug-hot">}}
89+
**Estimated time: 2–3 hours**
90+
{{< /alert >}}
91+
92+
Pacing depends on your experience with embedded Rust and Slint.
93+
94+
## Target Audience
95+
96+
This workshop is suitable for:
97+
98+
- Embedded developers with C/C++ background exploring Rust
99+
- Rust developers curious about no_std embedded development
100+
- Anyone interested in building fast, modern GUIs for microcontrollers
101+
102+
Basic knowledge of embedded systems and Rust syntax is helpful but not required.
103+
104+
## Support and Feedback
105+
106+
If you get stuck or have feedback, please open a [discussion on GitHub](https://github.com/espressif/developer-portal/discussions) or reach out to the [Slint Discord](https://slint.dev/community.html).
107+
108+
## Feedback and Contributions
109+
110+
This workshop is available on GitHub and welcomes contributions and improvements. If you encounter issues or want to propose updates, feel free to [open a discussion or pull request](https://github.com/espressif/developer-portal/discussions).
111+
112+
## Goals
113+
114+
By the end of this workshop, you will:
115+
116+
- Be able to create a UI with Slint in Rust using `no_std`
117+
- Deploy graphical apps to ESP32-S3 boards with display and optional touch
118+
- Understand how to separate logic from presentation with properties and callbacks
119+
- Integrate the Slint runtime with an embedded framebuffer and event loop
120+
121+
---
122+
123+
124+
## Credits
125+
126+
This workshop was created in collaboration between [Espressif Systems](https://www.espressif.com), [Slint](https://slint.dev/esp32), [M5Stack](https://m5stack.com), [ESoPe](https://esope.de), and [Schukat](https://shop.schukat.com/de/de/EUR/search/esope).
127+
128+
If you are interested in organizing a workshop or need support, we recommend reaching out to the trainer: [Michael Winkelmann](https://winkelmann.site/).
129+
130+
Let's get started: [Assignment 1](assignment-1)
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
---
2+
title: "Assignment 1: Environment Setup"
3+
date: 2025-06-03T00:00:00+01:00
4+
showTableOfContents: true
5+
series: ["slint-no-std"]
6+
series_order: 1
7+
showAuthor: false
8+
---
9+
10+
## Assignment 1: Environment Setup
11+
12+
In this assignment, we will set up the Rust development environment for ESP32-S3 programming using the official [`espup`](https://github.com/esp-rs/espup) tool.
13+
14+
Slint supports building applications for microcontrollers like the ESP32-S3 using Rust in both `no_std` (bare-metal) and `std` (ESP-IDF) modes. **This workshop primarily uses the `no_std` approach** due to its simplicity and better performance.
15+
16+
---
17+
18+
### Step 1: Install Rust
19+
20+
Install the Rust stable toolchain using `rustup` if you haven't already:
21+
22+
```sh
23+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
24+
```
25+
26+
Once installed, ensure you have the latest stable toolchain:
27+
28+
```sh
29+
rustup update
30+
```
31+
32+
---
33+
34+
### Step 2: Install `espup`
35+
36+
We recommend installing `espup` using Cargo:
37+
38+
```sh
39+
cargo install espup --locked
40+
```
41+
42+
Alternatively, you may use pre-built binaries or `cargo-binstall` (see espup GitHub README for details).
43+
44+
---
45+
46+
### Step 3: Run `espup install`
47+
48+
To install the toolchain for **no_std** development (which includes the GCC linker), run:
49+
50+
```sh
51+
espup install
52+
```
53+
54+
This will install:
55+
56+
- The Espressif Xtensa Rust toolchain
57+
- LLVM with Xtensa backend
58+
- GCC cross compiler
59+
- `export-esp.sh` file containing environment variables
60+
61+
You may customize targets like so:
62+
63+
```sh
64+
espup install --targets esp32s3
65+
```
66+
67+
⚠️ Do **not** use the `--std` flag — we are developing in `no_std`.
68+
69+
---
70+
71+
### Step 4: Source the environment variables (Unix-based systems)
72+
73+
After `espup install`, you'll find `export-esp.sh` under `$HOME`.
74+
75+
You need to load this file to correctly configure your environment:
76+
77+
#### Temporary (for current shell)
78+
79+
```sh
80+
. $HOME/export-esp.sh
81+
```
82+
83+
#### Persistent (recommended)
84+
85+
Append the export file to your shell configuration (e.g. `.bashrc`, `.zshrc`):
86+
87+
```sh
88+
cat $HOME/export-esp.sh >> ~/.bashrc
89+
```
90+
91+
Then:
92+
93+
```sh
94+
source ~/.bashrc
95+
```
96+
97+
On **Windows**, this is done automatically.
98+
99+
---
100+
101+
### Step 5: Verify the installation
102+
103+
Check that the Rust Xtensa toolchain is active:
104+
105+
```sh
106+
rustc --version
107+
cargo --version
108+
```
109+
110+
Check that `espflash` is installed:
111+
112+
```sh
113+
cargo install espflash
114+
```
115+
116+
You're now ready to compile `no_std` Rust applications targeting the ESP32-S3!
117+
118+
---
119+
120+
## Development Approach: `no_std` vs `std`
121+
122+
### `no_std` Approach
123+
124+
**This workshop uses the `no_std` approach by default.** The setup above is perfect for `no_std` development.
125+
126+
**Project Directory Structure:**
127+
```
128+
esp32/no_std/
129+
├── m5stack-cores3/ # M5Stack CoreS3 implementation
130+
├── esope-sld-c-w-s3/ # ESoPe board implementation
131+
├── esp32-s3-box-3/ # ESP32-S3-BOX-3 implementation
132+
└── esp32-s3-lcd-ev-board/ # LCD-EV board implementation
133+
```
134+
135+
### `std` Approach
136+
137+
**If you specifically need ESP-IDF/std features**, you can also set up for `std` development:
138+
139+
```sh
140+
# For std development, install with --std flag
141+
espup install --std
142+
```
143+
144+
**Project Directory Structure:**
145+
```
146+
esp32/std/
147+
├── m5stack-cores3/ # M5Stack CoreS3 std implementation
148+
├── esope-sld-c-w-s3/ # ESoPe board std implementation
149+
├── esp32-s3-box-3/ # ESP32-S3-BOX-3 std implementation
150+
└── esp32-s3-lcd-ev-board/ # LCD-EV board std implementation
151+
```
152+
153+
**Note:** `std` approach requires additional ESP-IDF setup and is more complex. **We recommend starting with `no_std`** for this workshop.
154+
155+
---
156+
157+
### Next Step
158+
159+
Now that your environment is ready, let’s run our first Slint GUI app on the desktop.
160+
161+
[Continue to Assignment 2](../assignment-2/)
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
2+
3+
---
4+
title: "Assignment 2: Run GUI on Desktop"
5+
date: 2025-06-03T00:00:00+01:00
6+
showTableOfContents: true
7+
series: ["slint-no-std"]
8+
series_order: 2
9+
showAuthor: false
10+
---
11+
12+
In this assignment, you will run your first Slint application on your desktop. This is a crucial step because Slint is designed to support a cross-platform development workflow — you can develop and preview your UI logic on a desktop machine, and later run it unmodified on an embedded device.
13+
14+
## Goals
15+
16+
- Run a simple Slint-based GUI desktop application
17+
- Learn about the `.slint` UI syntax
18+
- Understand the view-model structure used in this workshop
19+
20+
## Prerequisites
21+
22+
- Rust stable installed with `espup` (see Assignment 1)
23+
- Git
24+
- A desktop platform (Windows, Linux, macOS)
25+
- Rust GUI dependencies installed via `cargo build`
26+
27+
## Step-by-Step Instructions
28+
29+
### 1. Clone the Example Repository
30+
31+
We will use a ready-to-run version of the project from the Slint ESP workshop:
32+
33+
```bash
34+
git clone https://github.com/WilstonOreo/slint-esp-workshop.git
35+
cd slint-esp-workshop/winit
36+
```
37+
38+
### 2. Run the Application
39+
40+
Inside the `winit` directory, launch the desktop version with:
41+
42+
```bash
43+
cargo run --release
44+
```
45+
46+
You should see a GUI window open with two tabs:
47+
48+
- **Slint logo page** – a static graphical layout
49+
- **Wi-Fi list placeholder page** – currently empty, but will later show available access points
50+
51+
If the application launches and you can switch tabs, you're ready to proceed.
52+
53+
---
54+
55+
## About `.slint` Files
56+
57+
The GUI is defined in `.slint` files under the `ui/` directory. Here's a brief overview:
58+
59+
- `appwindow.slint`: the top-level window layout
60+
- `pages.slint`: contains the individual pages (e.g. logo and Wi-Fi list)
61+
- `widgets.slint`: reusable UI elements
62+
- `style.slint`: styling definitions (colors, spacing, fonts)
63+
- `viewmodel.slint`: defines properties exposed to Rust (e.g. selected tab)
64+
65+
### Example:
66+
67+
```slint
68+
export component MainWindow inherits Window {
69+
in-out property <int> current_tab: 0;
70+
71+
TabWidget {
72+
current-tab: root.current_tab;
73+
Tab { title: "Logo"; /* ... */ }
74+
Tab { title: "Wi-Fi"; /* ... */ }
75+
}
76+
}
77+
```
78+
79+
This declarative syntax is both concise and powerful, making UI development intuitive.
80+
81+
---
82+
83+
## View Model Architecture
84+
85+
Slint supports two-way binding between Rust and UI via `in-out` properties and callbacks. The workshop uses a basic MVVM (Model-View-ViewModel) pattern:
86+
87+
- `.slint` defines structure & exposed properties
88+
- `viewmodel.rs` or `main.rs` binds data to UI
89+
- Events are handled in Rust and forwarded to Slint
90+
91+
This keeps rendering declarative and logic testable.
92+
93+
---
94+
95+
## Summary
96+
97+
You’ve now successfully launched a desktop GUI written in Slint. In the next step, you’ll bring this application to your embedded device.
98+
99+
[Continue to Assignment 3 →](../assignment-3/)

0 commit comments

Comments
 (0)