Daniel Bank has been working with Snips offline machine learning stack and explains the ins and outs of cross compiling for a different architecture than you're machine.
Why Cross compile via @jacobRosenthal
We can technically compile just fine for rapsberry pi if we add the target:
rustup target add armv7-unknown-linux-gnueabihf
But well get this error when we build for our target
$ cargo build --target armv7-unknown-linux-gnueabihf Compiling pi-example v0.1.0 (/Users/jacobrosenthal/Downloads/pi-example) error: linker `arm-linux-gnueabihf-gcc` not found | = note: No such file or directory (os error 2) error: aborting due to previous error error: Could not compile `pi-example`. To learn more, run the command again with --verbose.
So we need a linker, in this case its probably called something very near arm-linux-gnueabihf-gcc
These toolchains are generally very available for bare metal "no_std" cortex devices. You might remember from other workshops they just have us quickly install the toolchain as the first step
But were not targeting "no_std" raspberry pi, were targeting linux on top of pi, so we can use all the Rust "std" libraries.
As an aside, if you want to check out no_std raspberry pi stuff, I recommend Phillip Oppermans blog series which is basically a CS Degree in building an operating system from scratch on the rasperry pi
So if were in linux its probably actually not that hard to get the raspberry pi toolchain linker. Something like
sudo apt-get install gcc-4.7-multilib-arm-linux-gnueabihf would probably work
Then create a .cargo/config file and add
[build] target = "armv7-unknown-linux-gnueabihf" [target.armv7-unknown-linux-gnueabihf] linker = "arm-linux-gnueabihf-gcc-4.7"
cargo build should work for you! Congrats you dont need cross (today).
But on Mac that toolchain is for some reason just not commonly hosted anywhere in brew etc. The best Ive found is this million page medium article Setup GCC 8.1 Cross Compiler Toolchain for Raspberry Pi 3 on macOS High Sierra
But you know whats better than doing all that yourself and polluting your machine? Having someone else do work for you and packaging it in a reusable cross platform way. Maybe with something like .. a docker container.. Enter Cross
Using Cross to cross compile via @danielbank
Add Rust targets
rustup target add armv7-unknown-linux-gnueabihf # Pi rustup target add arm-unknown-linux-gnueabihf # Pi Zero rustup target list
cargo install --force --git https://github.com/rust-embedded/cross cross
Docker has to be running or you will get errors!
Go to the code directory you want to build
Build the code with cross
cross build --target=armv7-unknown-linux-gnueabihf
Common Reasons Your Build is Failing
Did you use
cross? If cross compiling, you must use
Did you specify a target? If you don't specify a target in the build command or haven't set it up in a .cargo/config,
crosswill just build for your local architecture.
Are you getting errors similar to the following?
error: failed to load source for a dependency on \`tract-core\`
I was able to resolve these errors by specifying a
cross build --target=armv7-unknown-linux-gnueabihf --manifest-path=examples/tensorflow-mobilenet-v2/Cargo.toml
Is there a supported Docker image for the target architecture? I noticed when trying to build for a Pi Zero that I couldn't find a Docker image for the
arm-unknown-linux-gnueabihftarget. In my case, someone published their own Docker image which I found from a GitHub Issue
Unable to find image 'japaric/arm-unknown-linux-gnueabihf:latest' locally
Hands on: blink an led on a raspberry pi via @jacobRosenthal
My crate you should know is Rppal which has the fastest gpio access for raspberry pi
Theres a great blink example included
On your machine, assuming you have rust and cross installed lets make a new project with
cargo new pi-example && cd pi-example
Then we have to add the rppal dependency to Cargo.toml like
[dependencies] rppal = "0.11.3"
Now lets replace the src/main.rs with that example above. Ive put an led on our pi here on pin14 so change 23 to 14. This is agreat pinout site for raspberry pi
And were ready, compile with cross as daniel showed
cross build --target armv7-unknown-linux-gnueabihf
Now lets push our compiled executable over to a pi. Im going to use pinode1 and a tool called scp to send files over ssh to another device. Your compiled file is probably sitting at target/armv7-unknown-linux-gnueabihf/debug/pi-example so lets
scp target/armv7-unknown-linux-gnueabihf/debug/pi-example [email protected]:/home/pi
And now lets ssh into our pi and run it like
ssh [email protected] then
Now hopefully you can see your led blinking away. You can [ctrl-c] to kill the program and type 'exit' to get out of ssh back to your computer and make some changes. Can you blink at a different rate, a random rate, a sin wave so it looks like a heart beat? println! some stuff? Theres also i2c and many other protocols in the rppal library for you to try. Find some sensors and motors and other hardware.