Arduino is an AVR microcontroller made simpler for beginners in embedded systems. While the Arduino UNO is used in this article, it is easier to follow the procedure specified here for other boards.
Rust is a systems programming language that perfectly suits low level systems and communicates properly with hardware systems. It was designed to be a modern-day alternative to C++, but with more memory safety and efficiency, as well as speed.
This tutorial is aimed at beginner- to intermediate-level Rust or embedded systems developers looking to learn how to run Rust on a microcontroller. The prerequisites for going through this article includes:
- Knowledge of Rust language
- Development environment for Rust language
- Basic knowledge of Arduino
- Basic usage of a Linux environment
Jump ahead:
- Why Rust for embedded systems?
- What is the Arduino UNO?
- Tooling
- Installation and setup
- Starting a new Arduino project
- Configuring the microcontroller for flashing
- Other projects
- Further support for embedded Rust development
Why Rust for embedded systems?
Embedded systems technology has lacked novelty for decades. The language of choice for programming lightning-fast, embedded devices has been C/C++ for a long time, but Rust provides even faster development support.
Rust is a great fit for embedded systems development because it is:
- Highly interoperable with C codebases
- Portable and lightweight
- A powerful concurrency model
- Robust support for different microcontrollers
- Memory safe, so there will be no problems due to memory
If you have already programmed Arduinos in C++, it will be relatively easy to transition to doing so with Rust, once you master the basics. You can learn more about embedded Rust here. You can also see the available microcontroller crates here.
What is the Arduino UNO?
The Arduino UNO is based on the ATMega328P under the AVR microcontrollers family developed by Atmel. The Arduino can be programmed with its programming language, which is derived from C++ using the Arduino IDE editor, but since it is also an open source project, other systems-compatible programming languages can also be used to program the Arduino.
The normal procedure for embedded systems development with the Arduino involves the following steps:
- Sketching the electrical diagram of the intended circuit
- Connecting the electrical components to match the diagram
- Writing the program logic to control the circuit as desired
- Connecting the microcontroller via the USB cord to the computer
- Flashing (or uploading) the program from the computer onto the board’s Flash memory
This article focuses on the third through fifth steps, but the wiring for the tutorial will be made available.
Tooling
To follow this article, you will need some software installed along with some hardware.
Software needs
- A machine for writing, compiling and flashing the program to the board
- Cargo installed (see https://rustup.rs)
- Rust nightly compiler version installed
Hardware needs
- The Arduino board
Installation and setup
Using Avrdude
A Hardware Abstraction Layer (HAL) is required to run Rust on AVR microcontrollers and other common boards. To get this, you need the nightly Rust compiler that compiles Rust code to AVR on your machine. Run the command below to install it:
rustup toolchain install nightly
On Windows
On Windows, you will need to install Scoop via Powershell using the command:
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser # Needed to run a remote script the first time irm get.scoop.sh | iex
The output at the end should be:
Afterwards, run the following commands to install avr-gcc
and avrdude
:
scoop install avr-gcc
scoop install avrdude
On macOS
On macOS, simply set up the homebrew-avr tap and run the following commands:
xcode-select --install # for the fist time brew tap osx-cross/avr brew install avr-binutils avr-gcc avrdude
On Linux
If you use a Linux distribution like Ubuntu, the command is:
sudo apt install avr-libc gcc-avr pkg-config avrdude libudev-dev build-essential
There is an installation guide for all operating systems here, should you come across an obstacle following the guide above.
After either of these steps, the next step is to install the ravedudetool for flashing the microcontroller board against cargo
:
cargo +stable install ravedude
This tool handles everything from finding the board, flashing the board, and listening to connections. You simply have to run the cargo run
command.
Starting a new Arduino project with avrdude
Starting a new project is made simpler with the cargo-generate
crate. Simply run the following commands consecutively to create a new project:
cargo install cargo-generate cargo generate --git <https://github.com/Rahix/avr-hal-template.git>
After running the command, you should see an input field to specify a name for your project. This article uses rust-x-arduino
as the project name.
After inputting your preferred name, click Enter. The next log shows a list of microcontrollers available under the avrdude
template. This article uses the Arduino UNO, a variant that is readily available to everyone.
Navigate into the project after the build, and open the folder as a project in your preferred code editor. The project structure should look like the image below:
NB: If there is an error in installing the libudev-sys
crate, you will have to include it in your cargo.toml
file under dependencies:
[dependencies] libudev-sys = "0.1"
The libudev Rust binding is a crate that provides declarations and linkage for the libudev
C library. It is Linux-specific, so it is not available for Windows or OSX operating systems.
Alternatively, you can run the command below to install the libudev-sys
crate:
sudo apt-get install libudev-dev
You can consult the libudev-sys repository in case of further issues arising from pkg-config
.
Moving on, you can build the project with the build command:
cargo build
It takes a while, since it is a CPU-intensive task. Afterward, you will find a .elf
file under target/avr-atmega328p/debug/
. To run your own program, you can edit the main.rs
file, which already contains an example code for a basic LED Blinking program:
#![no_std] #![no_main] use panic_halt as _; #[arduino_hal::entry] fn main() -> ! { let dp = arduino_hal::Peripherals::take().unwrap(); let pins = arduino_hal::pins!(dp); let mut led = pins.d13.into_output(); loop { led.toggle(); arduino_hal::delay_ms(1000); } }
Understanding the above embedded Rust code
From the first two lines of code, it is clear that there is no standard library and no main, since it is an embedded project with no operating system.
The line #[arduino_hal::entry]
specifies the entry point in the program. The line uses panic_halt as _;
is used to handle panics.
In the main function, the Peripherals are unwrapped. In embedded Rust, Peripherals refer to the components that make sense of their surroundings and interact with humans. They include sensors, actuators, motor controllers, as well as the fundamental parts of the microcontroller like the CPU, RAM, or Flash Memory. You can learn more about Peripherals in the embedded Rust book.
Next, we gain access to the pins in the Arduino board in order to set the digital output for the default pin (D13) to high
.
Every Arduino program contains the void setup()
and the void loop()
. We have just gone through the setup; the other part of the code shows the looping.
The toggle
method in the loop is used to turn the LED on and off, while the delay_ms
method is used to delay the loop by the specified milliseconds.
Configuring the microcontroller for flashing
When working with the Arduino microcontroller in the official Arduino IDE, you simply have to write the program in Arduino, which is C++-based, and upload the program source file to the board via the USB port.
With Rust, we will be following a longer but similar procedure. Start by listing the open USB ports in your machine with the Linux command:
lsusb
If you have your Arduino board plugged into your device via the USB, you should see the name of the USB connected to the Arduino board like in the image below:
Next, we will be setting the serial com port for ravedude
with the script:
export RAVEDUDE_PORT=/dev/ttyUSB0
This tells ravedude
which port the Arduino is connected to. Running the command below will build and flash the program into the Arduino:
cargo run
Output on the microcontroller
When the program is uploaded into the microcontroller, the Arduino will behave as programmed. In this case, the LED lights on the board will blink according to the time intervals specified in the program.
Other projects
It is worth mentioning that there is an examples directory on the avr-hal
crate/repository, where you can find example Arduino project programs to try out. For example, if you are using the Arduino UNO, you can select it, navigate to the src/bin
directory, and find different programs compatible with the Arduino UNO board.
If you wish to write your own project, you have to generate the AVR-HAL template like we did in the previous section.
Further support for embedded Rust development
The official documentation for embedded Rust development is available here, and the book is here. There is also a GitHub repository where all resources related to embedded Rust are stored; it can serve as a useful starting point for trying out new things. It is based off of the official Rust on Embedded Devices Working Group.
If you wish to go further into embedded development with Rust, you can check out an entire playlist by Vers Binarii here.
The post A complete guide to running Rust on Arduino appeared first on LogRocket Blog.
from LogRocket Blog https://ift.tt/m8p4hxG
Gain $200 in a week
via Read more