Exploring the World of ESP32S3 and Rust Embedded Systems

Welcome to my blog, where we explore the ESP32S3 microcontroller unit (MCU) and Rust embedded systems together. Starting from the basics, we’ll walk through setting up the hardware, software, and Rust development environment. Using Visual Studio Code (VSCode) as our IDE, we’ll dive into the ESP32 hardware step-by-step, uncovering its capabilities with Rust along the way.


So, why Rust and ESP32S3? Let’s start with the ESP32. It’s the most popular MCU in the hacker/maker space, boasting features such as Wi-Fi and Bluetooth capabilities,
ESP Now, mesh, Matter, and much more. Not to mention, it has official support for
Rust.


As for Rust, it’s touted to be superior to C in terms of manageability and, more
importantly, memory safety. According to Chromium, 70% of their critical bugs
stem from memory safety issues. If you’re familiar with IoT and embedded systems,
you’ll know that they can be a security nightmare. Once deployed, these systems
are difficult to fix or update. There are many more reasons why Rust is great for
IoT/embedded systems, but they’re too numerous to list here. For a more in-depth
discussion, I recommend this excellent article here.

Pre-requisites to follow along:

  • Basic MCU knowledge
  • Basic coding skills

Hardware:

We are going to be using the ESP32s3 from Espressif. I will be using the LilyGo TCameraS3 board because it’s the one that I have on hand. It has a camera and a
small screen which I plan to use in future posts. However, you can use any other
ESP32s3 dev Board (1, 2, 3, 4). If you don’t have one or are too lazy to get one, you
can simulate the ESP32s3 at Wokwi here.

Development Environment Setup

Let’s set up our development environment. I am using Windows, so the following is
only applicable to Windows. If you are using Linux, you probably already know
what you are doing. Here’s what we need to install:

1. Rust

  • The primary way to install Rust is to go to the Rustup website, download and
    run rustup‑init.exe. After the installer finishes, you should see a screen like this.

  • To test if Rust is installed properly, close your cmd and open a new one and run rustc –version. If Rust is installed, you should see.

2. ESPUP

We need the necessary toolchain to develop for our esp32-s3 Xtensa architecture.
Fortunately, there is a tool for this that simplifies the whole process: ESPUP.
Begin the installation of ESPUP by opening cmd and running the following
command:

cargo install espup

To test if ESPUP is properly installed, run espup.

To install all the necessary tools to develop Rust, run espup install.

3. Git, Python, and ldproxy

These are necessary to build Rust std applications (more on this later).
For Python, visit the official Python website, download the 64-bit installer of the
latest stable release, and run the installer.

Make sure you select both checkboxes at the bottom (run as administrator, add
Python to PATH).

If successful, run python on cmd (you may need to close and open cmd). You
should see something like this.

To install ldproxy, run cargo install ldproxy.

Lastly, to install Git, the simplest way is to use winget by running the followingcommand: winget install –id Git.Git. It may prompt you Yes or no, type Y.

To test, run git on a fresh terminal(cmd), and it should output .

4. Additional Tool: Cargo Generate

To make our lives easier, we need to install one more tool: cargo generate.This tool
allows us to create projects from templates.


Instead of creating a new project from scratch every time and filling in every detail,
we can use cargo generate to create a ready project for us.

To install, simply run cargo install cargo-generate.

At this point, we can actually code and even run it on hardware or simulate it on
Wokwi. But before that, let’s set up an IDE.

5. Setting Up the IDE

I prefer Visual Studio Code (VSCode) as it’s free and supports almost every
language out there through its community extensions. These extensions will make
our life much easier.


First, download VSCode from here. Once it is downloaded, run the installer
VSCodeUserSetup and follow the installer wizard.

Open VSCode and you should see the Visual Studio welcome screen.

By default, VSCode doesn’t support Rust, but all we have to do to let VSCodesupport it is to install the rust-analyzer Extension. Go to the extensions panel orpress Ctrl+Shift+X and search for rust-analyzer and install it.

Now that we are done with installing tools, we can finally start to code.

s

6. Creating a New Rust Project

Let’s create a new Rust project from a template using cargo generate. This will save
us a lot of time and give us a configured project.


Create a new folder where you want to keep your Rust projects. I named mine
ESPRust. Open cmd and navigate to it. Or you can open the folder using VSCode
and use the built-in terminal (`Ctrl+“).


Then type and run cargo generate esp-rs/esp-template. It will prompt you to enter
a project name. Enter ESPRust_hello. Then it will prompt you to select an MCU. I am using ESP32-s3. Finally, it will ask whether to configure advanced template options.
Select False.

Open explorer on VSCode (Ctrl+Shift+E). You should see the newly created project
under ESPRust. If not, hit refresh on explorer. That’s it, we have a fully configured
project.


Now that we are done with installing tools, we can Finally start to code.

7. Understanding the Code and Project Structure

Now we can upload/flash the code to our ESP32 and see it working. But first, let’s
take a quick look at the code and project structure.


src/main.rs: This is the main source file which contains our main function fn
main().


.cargo/config.toml: The configuration file for cargo itself. Here you can define
build options like target, compiler, and more. If you open config.toml, you will see
this line runner = “espflash flash –monitor”. This tells cargo and by extension rust-
analyzer which command to run when you click on RUN on VSCode. In our case, it
runs espflash.exe. This will upload the code to our ESP32 and then (–monitor)
opens a serial com to our ESP32.


Cargo.toml: This is where you write your project dependencies. For example, if you
need to print to UART, USB Serial JTAG, you can add esp-println under
[dependencies] which in our case is already added by the template.

8. Building and Uploading the Code to Our Hardware

Finally, let’s build and upload the code to our hardware.


To build and run the project, we need to use Cargo run. This will build the project
and then upload it to the connected ESP32 hardware. We can use the VSCode
terminal (`Ctrl+“) and type:

cd ESPRust_hello
Cargo run

Or we can simply click on run that appears above fn main() on the main.rs file.

Open explorer (Ctrl+Shift+E), navigate to src/main.rs, open it, wait a few seconds,
and a play/run button should appear.

If everything is done correctly, we should see the project compiling in the terminal
and if your ESP32 is connected, we should see hello world on the terminal with a
loop. In some ESP32 boards, you may need to press and hold the boot button on
the board and then connect the USB.

9. Modifying the Code

Let’s personalize the code a bit and make it ours.. We’ll change the “Hello World”
message to “Hello Rust” and add an integer that increments in a loop.

println!("Hello Rust!");
let mut x = 1;
loop {
x = x + 1;
println!("Loop...{}",x);
delay.delay_ms(500u32);
}

After making these changes, run the program again.

Open explorer (Ctrl+Shift+E), navigate to src/main.rs, open it, wait a few seconds,
and a play/run button should appear.

If everything is done correctly, we should see the project compiling in the terminal
and if your ESP32 is connected, we should see hello world on the terminal with a
loop. In some ESP32 boards, you may need to press and hold the boot button on
the board and then connect the USB.

10. Experimenting with the Code

Now that you’ve made some changes, feel free to play around with the code. Add
your own touch to it and familiarize yourself with the Rust environment.


This hands-on experience will help you understand the concepts better.

11. What’s Next?

That’s it for the first part of this series. In the next part, In the next part, we’ll
explore more about the whole Standard library vs non-std and get a little deeper.
Stay tuned!


Remember, the best way to learn is by doing. Don’t hesitate to experiment and
make mistakes. That’s all part of the learning process. Happy coding! 🙂

Leave a Comment