I love writing Arduino code for STM32
microcontrollers but wanted to expand my skill
set to the awesome Rust programming language. Having looked into Embedded
Rust, I concluded that the level of
Rust knowledge required was beyond my current ability to understand and modify.
(Also, because much of the Rust code required to replace the Arduino code for peripherals,
serial comms and the like must be declared unsafe
, I couldn't see a big advantage
to giving up the convenience of Arduino to move entirely to Rust.) To keep the
best of both worlds – the simplicity of the Arduino approach and the
safety of Rust – I came up with this minimal example of how you
can call Rust code from an Arduino sketch on an STM32 microcontroller.
The very simple example I am using is adapted from Amir Shrestha's blog post. In this example, your Arduino (C++) code calls a Rust function to add two integers together, and then reports the resulting sum in a loop.
-
An STM32Fxx microcontroller. (The STM32F411 "Black Pill" development board is a great way to get started!)
-
Linux OS
To build the example you should edit the Makefile to select for your boards's generation,
part number, and variant. (Examples for a few boards are already provided, and you can see all
the options here.)
Then simply run the command
make
. To upload (flash) the resulting sketch onto your microcontroller
board, put the board into bootloader mode (typically by connecting two
pins
or pressing a boot
button before plugging in), and type make upload
. You can then type make listen
(or use the Arduino serial
monitor) to see a sequence of 7s resulting from the addition of 3 and 4 in the
Rust code.
The main obstacle to calling Rust code from Arduino is linking the compiled Arduino and Rust code together into a single ELF binary. To overcome this problem, the Makefile does the following:
-
Compiles the Rust code into a static library libmath.a via
cargo build
-
Compiles the Arduino sketch using
arduino-cli compile
, which builds the object files and library for the Arduino code. This command will fail to complete because of the missing object code for the Rust function, but prefacing thearduino-cli
command with a hyphen tells the Makefile to continue to the next step. -
Links the Arduino and Rust object code and libraries with an explicit call to arm-none-eabi-gcc.
The current example uses a pure function (no side effects) and passes and returns a simple datatype (integer). Current work on this project involves supporting side effects in the Rust code and passing and returning structured datatypes like tuples.