I wanted to do some funky type conversions, for a piece of hardware that needed to be robust and not crash, well, C is kinda not really memory safe, what is? Rust! But running Rust on embedded hardware is finnicky and libraries and community support is hard to come by (although this has improved massively since I started this project), and interfaces with the hardware sensors are a nightmare to say the least.
This is meant to be more of a template rather than a tutorial
-
Dynamically link a Rust lib and C code on x86 -
Statically link a Rust lib and C code on x86 -
Cross compile a simple led C code for arm target
-
Cross compile a simple led Rust code for arm target
-
Cross compile and statically link a compiled Rust lib with C code -
Replicate on other machines to confirm procedures -
Return an array to a C function
-
You can use platformIO with VSCode which is much easier to do when using things like
Serial.print()
orDelay()
for LED blinks etc. -
Put the compiled Rust library in lib subfolder in the project folder
-
In the platform.ini add build flags
build_flags = =l<libname> -Llib/
Here are the steps I took to compile a rust library for the teensy 4.1 and statically linked it to a main.c file
-
Install rust and other tools (rustup, cargo etc.)
-
Add the compilation target (thumbv7em-none-eabi)
rustup target add thumbv7em-none-eabi
rustup target add thumbv7em-none-eabi --toolchain stable
-
Change up your Rust boilerplate code to the following
#![no_std]
this makes it so that the stdlib is not included in the compiled library
#![no_mangle]
this will not make changes to the functon name so that we can call Rust functions from C/C++We build using
cargo build --target thumbv7em-none-eabi
-
Create a .cargo/config file and add the following
target = "thumbv7em-none-eabi"
-
Compile C code to arm
sudo apt-get install gcc-arm-linux-gnueabi
sudo apt install gcc-arm-none-eabi
-
Create a Rust lib
-
Rename main.rs to lib.rs
-
Add function with the following syntax
#[no_mangle] pub extern "C" fn rust_test() -> u8 { 0 }
-
Change Cargo.toml to include
[lib] crate-type = ["staticlib"] [dependencies] panic-halt = "0.2.0"
-
Compile and link
NOTE: linked libraries for embedded devices without an operating system will need the static flag
gcc -o output main.c -l<libname> -L<libpath . for curr> --static
clang-10 -o output main.c -l<libname> -L<libpath . for curr> --static
-
-
Statically link using arm gcc
arm-linux-gnueabi-gcc-9 -static main.c -o static.out -labi -L.
-
Create a hex file using arm gcc
arm-linux-gnueabi-objcopy -O ihex <source file> <output file>
Resources
https://www.youtube.com/watch?v=kgW56enMVek
https://www.youtube.com/watch?v=rOMl9FHgZ_0
Additional Read
https://stackoverflow.com/questions/37912290/arm-linux-executable-mysteriously-runs-on-x86-64
Credits