Rustduino pt. I: setting up the development environment
This post details the steps needed to start programming an Arduino UNO
board using the rust
programming language and working on Mac OS.
Premise
As a software developer who has always focused on high-level languages and frameworks, I’ve been meaning to explore the world of system programming for quite a while. Beyond satisfying my general fascination with technology, I am convinced that spending some time closer to the hardware level will make me a better programmer overall and give me a chance to learn some valuable skills.
Fast forward to the ongoing winter festivities and I find myself, by coincidence, with everything I need to begin my discovery:
- some lovely spare time;
- an
Arduino UNO
board based on theATMega328P
microcontroller; - preliminary support for the microcontroller’s
AVR
architecture inrust
, an intriguing and relatively new programming language that was already on my list of things to play with in 2019.
I’ve decided to document my experiments in a series of blog posts, hopefully sparing a couple of headaches to other developers getting into these subjects. This first post deals with setting up the development environment. Although I work on a Mac and some of these instructions are specific to Mac OS, porting them to Linux should be relatively trivial.
Install XCode’s developer tools and Mac OS’ development headers
Start by installing XCode
’s command-line developer tools:
xcode-select --install
If on Mac OS 10.14 (Mojave) install the OS’ development headers:
sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /
Missing headers will result in issues while building the zlib
library and/or errors while unpacking tar
archives using python
’s zlib
module.
Install Python 2.7.x
Install python
via homebrew
:
brew update
brew install cmake openssl readline sqlite3 xz zlib python@2
Install the GCC AVR toolchain
Install the GCC AVR toolchain, once again via homebrew
:
brew update
brew tap osx-cross/avr
brew install avr-gcc # This takes a while!
This step requires compiling GCC, which takes ~30 minutes. Many thanks to all the partecipants in the discussion related to this issue on GitHub as it helped me figure out what I needed to install.
Install the standard rust
toolchain
Install the standard rust
toolchain by following the official guide. This will also install the rustup
toolchain management tool, which helps managing multiple rust
builds on the same machine.
Install the AVR rust
toolchain
Time to install the rust
toolchain that targets the AVR
architecture, which is the architecture of the ATMega328P
that powers the Arduino UNO
. I had to make a few small modifications to the steps in the repository’s README:
# Grab the avr-rust sources
git clone https://github.com/avr-rust/rust.git avr-rust
# Create a directory to place built files in
mkdir avr-rust-build
cd avr-rust-build
# Generate Makefile using settings suitable for an experimental compiler
../avr-rust/configure \
--enable-debug \
--disable-docs \
--enable-llvm-assertions \
--enable-debug-assertions \
--enable-optimize \
--enable-llvm-release-debuginfo \
--experimental-targets=AVR \
--prefix=/opt/avr-rust
# Build the compiler
make # This takes a while!
# Register the new toolchain with rustup
rustup toolchain link avr-toolchain <absolute path to avr-rust-build>/build/x86_64-apple-darwin/stage1
Compile the blink
example project
Now that the AVR toolchain is ready, it’s time to compile a small test program to later deploy on the Arduino UNO. blink
programs are simple loops that toggle the state of light-emitting components on and off and they are to system programming what hello, world!
programs are to normal programming. One such program is made available by the maintainer of the AVR
toolchain which we have just installed. The following instructions are taken directly from the official repo’s README:
git clone https://github.com/avr-rust/blink.git avr-rust-blink
cd avr-rust-blink
export RUST_TARGET_PATH=`pwd`
export XARGO_RUST_SRC=<absolute path to avr-rust>/src # not avr-rust-build!
rustup run avr-toolchain xargo build --target avr-atmega328p --release
If all goes well, this will produce an .elf
file at target/avr-atmega328p/release/blink.elf
.
Install the Arduino IDE and avrdude
Although we will not use it in the rest of this post, the official Arduino IDE will become necessary in the future. Download it from Arduino’s home page and install it as any other Mac OS application by moving it to the /Applications
folder. Use it from the command line as follows:
/Applications/Arduino.app/Contents/MacOS/Arduino
For the time being, however, avrdude
will take care of uploading compiled programs to the board. Install it from homebrew:
brew update
brew install avrdude
Deploy onto the Arduino UNO
Connect the Arduino UNO via USB to the Mac. It should come up as a /tty.usbmodem****
file in the /dev
directory. Use avrdude
to upload the compiled program to the board:
avrdude -v -p atmega328p -c arduino -P /dev/tty.usbmodem14201 -b 115200 -D -Uflash:w:"target/avr-atmega328p/release/blink.elf"
If everything goes well, one of the yellow LEDs on the board should start blinking at a leisurely pace. Hooray! Further useful pointers about uploading files to the board can be found here, here and here.
Conclusion
We can now cross-compile rust
programs and deploy them onto the Arduino UNO. Happy 2019!