mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-22 14:53:03 +00:00
203 lines
8.6 KiB
Plaintext
203 lines
8.6 KiB
Plaintext
= Starting a new project
|
||
|
||
Once you’ve successfully xref:#_getting_started[run some example projects], the next step is to make a standalone Embassy project.
|
||
|
||
== Tools for generating Embassy projects
|
||
|
||
=== CLI
|
||
- link:https://github.com/adinack/cargo-embassy[cargo-embassy] (STM32 and NRF)
|
||
|
||
=== cargo-generate
|
||
- link:https://github.com/lulf/embassy-template[embassy-template] (STM32, NRF, and RP)
|
||
- link:https://github.com/bentwire/embassy-rp2040-template[embassy-rp2040-template] (RP)
|
||
|
||
|
||
== Starting a project from scratch
|
||
|
||
As an example, let’s create a new embassy project from scratch for a STM32G474. The same instructions are applicable for any supported chip with some minor changes.
|
||
|
||
Run:
|
||
|
||
[source,bash]
|
||
----
|
||
cargo new stm32g474-example
|
||
cd stm32g474-example
|
||
----
|
||
|
||
to create an empty rust project:
|
||
|
||
[source]
|
||
----
|
||
stm32g474-example
|
||
├── Cargo.toml
|
||
└── src
|
||
└── main.rs
|
||
----
|
||
|
||
Looking in link:https://github.com/embassy-rs/embassy/tree/main/examples[the Embassy examples], we can see there’s a `stm32g4` folder. Find `src/blinky.rs` and copy its contents into our `src/main.rs`.
|
||
|
||
=== The .cargo/config.toml
|
||
|
||
Currently, we’d need to provide cargo with a target triple every time we run `cargo build` or `cargo run`. Let’s spare ourselves that work by copying `.cargo/config.toml` from `examples/stm32g4` into our project.
|
||
|
||
[source]
|
||
----
|
||
stm32g474-example
|
||
├── .cargo
|
||
│ └── config.toml
|
||
├── Cargo.toml
|
||
└── src
|
||
└── main.rs
|
||
----
|
||
|
||
In addition to a target triple, `.cargo/config.toml` contains a `runner` key which allows us to conveniently run our project on hardware with `cargo run` via probe-rs. In order for this to work, we need to provide the correct chip ID. We can do this by checking `probe-rs chip list`:
|
||
|
||
[source,bash]
|
||
----
|
||
$ probe-rs chip list | grep -i stm32g474re
|
||
STM32G474RETx
|
||
----
|
||
|
||
and copying `STM32G474RETx` into `.cargo/config.toml` as so:
|
||
|
||
[source,toml]
|
||
----
|
||
[target.'cfg(all(target_arch = "arm", target_os = "none"))']
|
||
# replace STM32G071C8Rx with your chip as listed in `probe-rs chip list`
|
||
runner = "probe-rs run --chip STM32G474RETx"
|
||
----
|
||
|
||
=== Cargo.toml
|
||
|
||
Now that cargo knows what target to compile for (and probe-rs knows what chip to run it on), we’re ready to add some dependencies.
|
||
|
||
Looking in `examples/stm32g4/Cargo.toml`, we can see that the examples require a number of embassy crates. For blinky, we’ll only need three of them: `embassy-stm32`, `embassy-executor` and `embassy-time`.
|
||
|
||
|
||
At the time of writing, embassy is already published to crates.io. Therefore, dependencies can easily added via Cargo.toml.
|
||
|
||
[source,toml]
|
||
----
|
||
[dependencies]
|
||
embassy-stm32 = { version = "0.1.0", features = ["defmt", "time-driver-any", "stm32g474re", "memory-x", "unstable-pac", "exti"] }
|
||
embassy-executor = { version = "0.6.1", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
|
||
embassy-time = { version = "0.3.2", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
|
||
----
|
||
|
||
Prior, embassy needed to be installed straight from the git repository. Installing from git is still useful, if you want to checkout a specic revision of an embassy crate which is not yet published.
|
||
The recommended way of doing so is as follows:
|
||
|
||
* Copy the required `embassy-*` lines from the example `Cargo.toml`
|
||
* Make any necessary changes to `features`, e.g. requiring the `stm32g474re` feature of `embassy-stm32`
|
||
* Remove the `path = ""` keys in the `embassy-*` entries
|
||
* Create a `[patch.crates-io]` section, with entries for each embassy crate we need. These should all contain identical values: a link to the git repository, and a reference to the commit we’re checking out. Assuming you want the latest commit, you can find it by running `git ls-remote https://github.com/embassy-rs/embassy.git HEAD`
|
||
|
||
NOTE: When using this method, it’s necessary that the `version` keys in `[dependencies]` match up with the versions defined in each crate’s `Cargo.toml` in the specificed `rev` under `[patch.crates.io]`. This means that when updating, you have to a pick a new revision, change everything in `[patch.crates.io]` to match it, and then correct any versions under `[dependencies]` which have changed.
|
||
|
||
An example Cargo.toml file might look as follows:
|
||
|
||
[source,toml]
|
||
----
|
||
[dependencies]
|
||
embassy-stm32 = {version = "0.1.0", features = ["defmt", "time-driver-any", "stm32g474re", "memory-x", "unstable-pac", "exti"]}
|
||
embassy-executor = { version = "0.3.3", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
|
||
embassy-time = { version = "0.2", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] }
|
||
|
||
[patch.crates-io]
|
||
embassy-time = { git = "https://github.com/embassy-rs/embassy", rev = "7703f47c1ecac029f603033b7977d9a2becef48c" }
|
||
embassy-executor = { git = "https://github.com/embassy-rs/embassy", rev = "7703f47c1ecac029f603033b7977d9a2becef48c" }
|
||
embassy-stm32 = { git = "https://github.com/embassy-rs/embassy", rev = "7703f47c1ecac029f603033b7977d9a2becef48c" }
|
||
----
|
||
|
||
There are a few other dependencies we need to build the project, but fortunately they’re much simpler to install. Copy their lines from the example `Cargo.toml` to the the `[dependencies]` section in the new `Cargo.toml`:
|
||
|
||
[source,toml]
|
||
----
|
||
defmt = "0.3.5"
|
||
defmt-rtt = "0.4.0"
|
||
cortex-m = {version = "0.7.7", features = ["critical-section-single-core"]}
|
||
cortex-m-rt = "0.7.3"
|
||
panic-probe = "0.3.1"
|
||
----
|
||
|
||
These are the bare minimum dependencies required to run `blinky.rs`, but it’s worth taking a look at the other dependencies specified in the example `Cargo.toml`, and noting what features are required for use with embassy – for example `futures = { version = "0.3.17", default-features = false, features = ["async-await"] }`.
|
||
|
||
Finally, copy the `[profile.release]` section from the example `Cargo.toml` into ours.
|
||
|
||
[source,toml]
|
||
----
|
||
[profile.release]
|
||
debug = 2
|
||
----
|
||
|
||
=== rust-toolchain.toml
|
||
|
||
Before we can build our project, we need to add an additional file to tell cargo to use the nightly toolchain. Copy the `rust-toolchain.toml` from the embassy repo to ours, and trim the list of targets down to only the target triple relevent for our project — in this case, `thumbv7em-none-eabi`:
|
||
|
||
[source]
|
||
----
|
||
stm32g474-example
|
||
├── .cargo
|
||
│ └── config.toml
|
||
├── Cargo.toml
|
||
├── rust-toolchain.toml
|
||
└── src
|
||
└── main.rs
|
||
----
|
||
|
||
[source,toml]
|
||
----
|
||
# Before upgrading check that everything is available on all tier1 targets here:
|
||
# https://rust-lang.github.io/rustup-components-history
|
||
[toolchain]
|
||
channel = "nightly-2023-11-01"
|
||
components = [ "rust-src", "rustfmt", "llvm-tools", "miri" ]
|
||
targets = ["thumbv7em-none-eabi"]
|
||
----
|
||
|
||
=== build.rs
|
||
|
||
In order to produce a working binary for our target, cargo requires a custom build script. Copy `build.rs` from the example to our project:
|
||
|
||
[source]
|
||
----
|
||
stm32g474-example
|
||
├── build.rs
|
||
├── .cargo
|
||
│ └── config.toml
|
||
├── Cargo.toml
|
||
├── rust-toolchain.toml
|
||
└── src
|
||
└── main.rs
|
||
----
|
||
|
||
=== Building and running
|
||
|
||
At this point, we‘re finally ready to build and run our project! Connect your board via a debug probe and run:
|
||
|
||
[source,bash]
|
||
----
|
||
cargo run --release
|
||
----
|
||
|
||
should result in a blinking LED (if there’s one attached to the pin in `src/main.rs` – change it if not!) and the following output:
|
||
|
||
[source]
|
||
----
|
||
Compiling stm32g474-example v0.1.0 (/home/you/stm32g474-example)
|
||
Finished release [optimized + debuginfo] target(s) in 0.22s
|
||
Running `probe-rs run --chip STM32G474RETx target/thumbv7em-none-eabi/release/stm32g474-example`
|
||
Erasing sectors ✔ [00:00:00] [#########################################################] 18.00 KiB/18.00 KiB @ 54.09 KiB/s (eta 0s )
|
||
Programming pages ✔ [00:00:00] [#########################################################] 17.00 KiB/17.00 KiB @ 35.91 KiB/s (eta 0s ) Finished in 0.817s
|
||
0.000000 TRACE BDCR configured: 00008200
|
||
└─ embassy_stm32::rcc::bd::{impl#3}::init::{closure#4} @ /home/you/.cargo/git/checkouts/embassy-9312dcb0ed774b29/7703f47/embassy-stm32/src/fmt.rs:117
|
||
0.000000 DEBUG rcc: Clocks { sys: Hertz(16000000), pclk1: Hertz(16000000), pclk1_tim: Hertz(16000000), pclk2: Hertz(16000000), pclk2_tim: Hertz(16000000), hclk1: Hertz(16000000), hclk2: Hertz(16000000), pll1_p: None, adc: None, adc34: None, rtc: Some(Hertz(32000)) }
|
||
└─ embassy_stm32::rcc::set_freqs @ /home/you/.cargo/git/checkouts/embassy-9312dcb0ed774b29/7703f47/embassy-stm32/src/fmt.rs:130
|
||
0.000000 INFO Hello World!
|
||
└─ embassy_stm32g474::____embassy_main_task::{async_fn#0} @ src/main.rs:14
|
||
0.000091 INFO high
|
||
└─ embassy_stm32g474::____embassy_main_task::{async_fn#0} @ src/main.rs:19
|
||
0.300201 INFO low
|
||
└─ embassy_stm32g474::____embassy_main_task::{async_fn#0} @ src/main.rs:23
|
||
----
|