Today, I'll be showing you how to use the Rust programming language on a Rust ESP board, a recent embedded platform packed with Wi-Fi and Bluetooth capabilities.
We won't go through the details of no_std
vs std
development, just know that the latter allows us to use full Wi-Fi and Bluetooth capabilities along with the actual entire Rust Standard Library with ease which is usually NOT straightforward but hey, this is 2023, enjoy!
The original article and associated examples are available in my Rust ESP Quickstart GitLab repository.
TL;DR
If you are already running Linux and just want to flash your ESP board with a fully configured Rust "Hello, World!" project, see the script/setup.sh
script, it should help you get started in no time. Be aware, though, that it has been made for a freshly installed 22.10 Ubuntu distribution and is untested on any other platform yet (i.e. use it at your own risks). On the other hand, please read on if you intend to walk the learning path instead.
Requirements
Here's everything we are going to need during our little adventure:
- A computer with internet access
- A Rust ESP Board (this is open hardware so you can either buy one or build one yourself!)
- A USB cable
- An empty USB stick that we are going to erase completely so don't forget to BACKUP YOUR DATA FIRST (A 16GiB one is fine)
- Less than an hour of your time
The OS
We'll be using a live 22.10 Ubuntu distribution so that:
- anyone with a decent computer can follow this guide
- our setups are the exact same, thus greatly reducing the rate of environment-related errors
- everything is instantly reversible, meaning that your computer will be left completely untouched
- we won't need to go through an actual Linux installation
One drawback of this solution is that each reboot will wipe the environment but feel free to actually install linux if persistence across said reboots is required.
Making a bootable USB stick
- Download the 22.10 "Kinetic Kudu" Ubuntu ISO image here
- Flash the USB stick using either
usb-creator-gtk
if running Linux orWin32DiskImager
if running Windows
Installing usb-creator-gtk
on Linux
Open a terminal (the default shortcut is Ctrl
+Alt
+T
on Ubuntu) and run those commands:
sudo apt update
sudo apt install --yes usb-creator-gtk
Installing Win32DiskImager
on Windows
Download the installer from the project's page and run it.
Flashing the USB stick
In both cases, we will need to select the ISO image we want to flash and the device we want to use then click the Write or Make startup disk button. The process should complete within a few minutes.
Booting Ubuntu
Let's ask ChatGPT how to do that:
![Booting from a USB stick](https://gitlab.com/cyril.marpaud/rust_esp_quickstart/-/raw/main/images/chatgpt_boot_from_usb.png "Booting from a USB stick")Thank you ChatGPT ! Finally, hit that Try Ubuntu button to be greeted with a GNOME desktop.
The next steps require internet access so connect to a Wi-Fi (see the top-right corner menu) or wired network if you want to go old-school.
The tools
Here, we are going to make heavy use of a terminal. On Ubuntu, you can open one by pressing Ctrl
+Alt
+T
. You might want to copy/paste the following commands to avoid typos but suit yourself!
Build dependencies
We need a few more packages than Ubuntu provides by default. Please bear with the trauma of installing them:
sudo add-apt-repository --yes universe
sudo apt install --yes clang curl git libudev-dev libssl-dev pkg-config python3-pip
Rust and Cargo components
We'll now use Rustup to install both Rust and Cargo (Rust's package manager):
curl --proto '=https' --tlsv1.2 --fail --show-error --silent https://sh.rustup.rs | sh -s -- -y
source "$HOME/.cargo/env"
rustup toolchain install nightly --component rust-src
Moreover, we need a few additional Cargo modules:
-
espflash
to flash the device (see espflash) -
ldproxy
to forward linker arguments (see ldproxy) -
cargo-generate
to generate projects according to a template (see cargo-generate)
cargo install espflash ldproxy cargo-generate
Generating a project
The awesome ESP IDF Template will save us the pain of configuring a fully functional project ourselves, use it like so:
cargo generate --git https://github.com/esp-rs/esp-idf-template cargo
During the process, you will be asked a few things:
- a Project Name. Go wild and use test-project, for instance
- an ESP-IDF native build version. Go with the stable one (it is v4.4 at the moment)
- an MCU. Our board is equipped with an ESP32C3
- support for dev containers. We don't need that for now so that's a false
- STD support. We're building an std app so that's a true
Hello, World!
Getting access to the USB peripheral
You might like "Permission Denied" errors. If not, those commands will create a udev rule to avoid that when accessing our board through USB:
echo "SUBSYSTEMS==\"usb\", ATTRS{idVendor}==\"303a\", ATTRS{idProduct}==\"1001\", MODE=\"0660\", GROUP=\"plugdev\"" | sudo tee /etc/udev/rules.d/99-esp-rust-board.rules > /dev/null
sudo udevadm control --reload-rules && sudo udevadm trigger
Flash, run & monitor
Now make use of that USB cable and connect the board to your computer, then run this simple yet elegant command:
cargo run
If everything goes smoothly, Cargo should build the project, flash it on the MCU and finally run it, meaning that a line reading "Hello, World!" should be displayed in the terminal. Hit Ctrl
+R
to restart the program (not very useful at that point but it might be later) or Ctrl
+C
to quit monitoring it.
Congratulations, you are officially programming Rust on your ESP board !
The IDE
We could configure Vim, Emacs or any other terminal-based IDE, but the low-friction solution is to use Visual Studio Code with the appropriate extensions. This way, we are only a few clicks away from syntax highlighting, code completion and much more.
VSCodium
It is the exact same as VSCode but without telemetry/tracking stuff, plus it uses MIT license (see the official website). Install and run it like so:
snap install codium --classic
codium
An Open Folder button should be visible in the explorer tab on the left. Click it to add our project to the workspace. We are now able to edit source code way more handily than in a terminal.
Extensions
Go to the extensions tab and type "rust analyzer" in the search bar, then click the install button ("Rust language support for Visual Studio Code"). That's it! You can find more information about it on the official website. The Even Better TOML and crates extensions might also be of interest to you.
Going further
The examples folder of this repository contains three projects:
- blink: makes the LED connected to GPIO7 blink
- i2c-sensors: read and display data from the embedded SHTC3 & ICM42670 I2C sensors (temperature, humidity, accelerometer & gyroscope)
-
Wi-Fi: very basic Wi-Fi connection + ping example, just uncomment and fill
WIFI_SSID
andWIFI_PWD
environment variables at the bottom of.cargo/config.toml
Conclusion
As a kid, I used to boot my sister's laptop from a live 8.04 "Hardy Heron" Ubuntu CD (you could order one for free back then!) to bypass her password protection. This way, no one ever knew what I was doing (meerely looking for cheat codes for the games I used to play at the time 😉️). Today, I still believe this technique is of great value to anyone wishing to try something out without breaking anything.
Growing up, I then had the pleasure to learn how embedded development can sometimes be a pain: messy setup, weird and abstruse error messages... But hopefully, it has been less than an hour since you began reading this article and you are now able to use a modern language with std
support on a recent Wi-Fi-enabled microcontroller. Ain't that marvelous ?
I hope you enjoyed it as much as I do, especially when considering the tremendous amount of work that was needed to make this so easy for us.
Cheers!
See also (aka useful links)
Documentation
Crates
- Board Support Package
- ESP32C3
no_std
Hardware Abstraction Layer - ESP32C3
std
Hardware Abstraction Layer esp-template
:no_std
project templateesp-idf-template
:std
-enabled project templateembedded-svc
: service-related traitsesp-idf-svc
:embedded-svc
implementationshared-bus
: share I2C/SPI/ADC buses between peripherals (namely: sensors)shtcx
: access the SHTC3 embedded temperature+humidity I2C sensoricm42670
: access the ICM42670 embedded temperature+accelerometer+gyroscope I2C sensor
Examples
Tutorials
Whoami
My name is Cyril Marpaud, I'm an embedded systems freelance engineer and a Rust enthusiast 🦀 I have nearly 10 years experience and am currently living in Lyon (France).
Top comments (0)