I am trying to setup a project for embedded experiments. I would like these all in one project where I can just run the example from the examples directory. However, when I run the command I get an error
cargo run --example 01-hello-world --release
Compiling esp32c6 v0.1.0 (/Users/wwaldner/dev/embed/xp/esp32c6)
error: invalid instruction `cargo:rustc-link-arg-bins` from build script of `esp32c6 v0.1.0 (/Users/wwaldner/dev/embed/xp/esp32c6)`
The package esp32c6 v0.1.0 (/Users/wwaldner/dev/embed/xp/esp32c6) does not have a bin target.
You probably want to use the target runner
field to either run the cross-compiled artifact in an emulator or flash it to an external device. And might need to change the crate-type
for the example to ["lib", "rlib"]
or similar.
This project seems to be doing exactly what I want, however I can't figure out how they got it to work.
https://github.com/eldruin/driver-examples
I have a .cargo/config.toml that specifies a runner...
.cargo/config.toml
[target.riscv32imac-unknown-none-elf]
runner = "espflash flash --monitor"
[env]
ESP_LOG="INFO"
[build]
rustflags = [
# Required to obtain backtraces (e.g. when using the "esp-backtrace" crate.)
# NOTE: May negatively impact performance of produced code
"-C", "force-frame-pointers",
]
target = "riscv32imac-unknown-none-elf"
[unstable]
build-std = ["alloc", "core"]
I can successfully 'run' the application with the file in src/main.rs, just by running cargo run --release
The reason some of those examples work with cargo run
is because they build native executables that run on the host. E.g. with linux-embedded-hal
: driver-examples/raspberrypi/Cargo.toml at 117dbe81e9d1927af1d1b0139ad31477dee23a2c · eldruin/driver-examples · GitHub
As long as you can make the examples using platform agnostic dependencies, you can run them in this manner, too. But the error in OP says you are using dependencies that can only run on the embedded device.
So is there no way to run the examples on the platform in the project using cargo.toml and .cargo/config.toml in the parent directory?
You can, but you should follow my initial suggestion.
The runner
field needs to be in Cargo.toml
; it is not recognized in config.toml
. (This is wrong; it needs to be in config.toml
, you have that much correct.)
And to fix the error message in OP, you need to set the crate-type
field in the appropriate [[example]]
table. I am not certain what the correct crate-type
should be for your ESP32 device. Maybe "lib"
? crate-type
needs to be in Cargo.toml
.
You may also have to specify --target
to get it all to worth seamlessly.
In my own embedded projects, I have been using either a cargo subcommand (like cargo-embed
) or a cargo alias that passes my default arguments, so I don't have to remember to do it all the time. In some cases, combining an alias with the runner
field.
I've also had some issues with the shared target/
directory when building both native host bins and embedded device bins in the same workspace. My workaround for that was adding --target-dir target-thumbv6
to the alias as well. That stores all of the build artifacts in target/target-thumbv6/
and avoids spurious rebuilds caused by rust-analyzer and other rustc
invocations for building the host tools.