DEV Community

Cover image for Embedded Rust on ESP32C3 Board, a Hands-on Quickstart Guide
Cyril Marpaud
Cyril Marpaud

Posted on • Updated on

Embedded Rust on ESP32C3 Board, a Hands-on Quickstart Guide

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

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


Enter fullscreen mode Exit fullscreen mode

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


Enter fullscreen mode Exit fullscreen mode

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


Enter fullscreen mode Exit fullscreen mode

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


Enter fullscreen mode Exit fullscreen mode

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


Enter fullscreen mode Exit fullscreen mode

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

Cargo generate answers

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


Enter fullscreen mode Exit fullscreen mode

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


Enter fullscreen mode Exit fullscreen mode

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


Enter fullscreen mode Exit fullscreen mode

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 and WIFI_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

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)