Appendix C: Cargo.toml Template

This appendix provides a complete, working Cargo.toml and .cargo/config.toml for an Embassy project targeting the STM32H743. Copy it as your starting point, then adjust the chip feature flag for your board.

Cargo.toml

[package]
name = "sensor-hub"
version = "0.1.0"
edition = "2021"

[dependencies]
# Embassy runtime
embassy-executor = { version = "0.7", features = ["arch-cortex-m", "executor-thread", "integrated-timers"] }
embassy-stm32 = { version = "0.2", features = ["stm32h743vi", "time-driver-any", "memory-x"] }
embassy-time = { version = "0.4", features = ["tick-hz-32_768"] }
embassy-sync = "0.6"

# Logging with defmt
defmt = "0.3"
defmt-rtt = "0.4"

# Cortex-M support
cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
cortex-m-rt = "0.7"

# Panic handler — logs panic message via defmt, then halts
panic-probe = { version = "0.3", features = ["print-defmt"] }

# Fixed-size data structures (no heap)
heapless = "0.8"

# Embedded HAL traits
embedded-hal = "1.0"
embedded-hal-async = "1.0"

# Optional: static_cell for safe static initialization
static_cell = "2"

[profile.release]
opt-level = "s"       # Optimize for size
debug = 2             # Keep debug info for defmt
lto = "fat"           # Link-time optimization
codegen-units = 1     # Better optimization, slower compile

.cargo/config.toml

[target.thumbv7em-none-eabihf]
runner = "probe-rs run --chip STM32H743VITx"

[build]
target = "thumbv7em-none-eabihf"

[env]
DEFMT_LOG = "debug"

Switching to a Different Chip

To target a different STM32, change three things:

STM32F411CE (Black Pill)

# In Cargo.toml — change the embassy-stm32 feature
embassy-stm32 = { version = "0.2", features = ["stm32f411ce", "time-driver-any", "memory-x"] }
# In .cargo/config.toml — same target (both are Cortex-M4F)
[target.thumbv7em-none-eabihf]
runner = "probe-rs run --chip STM32F411CEUx"

STM32G071RB (Nucleo — Cortex-M0+)

# In Cargo.toml
embassy-stm32 = { version = "0.2", features = ["stm32g071rb", "time-driver-any", "memory-x"] }

# Also change cortex-m critical section feature if needed
cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
# In .cargo/config.toml — different target for M0+
[target.thumbv6m-none-eabi]
runner = "probe-rs run --chip STM32G071RBTx"

[build]
target = "thumbv6m-none-eabi"

STM32U575ZI (Nucleo — Cortex-M33)

# In Cargo.toml
embassy-stm32 = { version = "0.2", features = ["stm32u575zi", "time-driver-any", "memory-x"] }
# In .cargo/config.toml — ARMv8-M target
[target.thumbv8m.main-none-eabihf]
runner = "probe-rs run --chip STM32U575ZITxQ"

[build]
target = "thumbv8m.main-none-eabihf"

Quick Reference: What to Change

ItemWhereExample
Chip modelCargo.toml embassy-stm32 featuresstm32f411ce
Build target.cargo/config.toml [build]thumbv7em-none-eabihf
probe-rs chip.cargo/config.toml runnerSTM32F411CEUx

Fun Fact: The probe-rs chip name uses the full ST part number suffix (like STM32F411CEUx), where U is the package type (UFQFPN) and x is a wildcard for temperature range. You can find the exact string by running probe-rs chip list | grep -i f411.

Minimal main.rs to Verify Setup

After creating these files, use this minimal main.rs to confirm everything compiles and runs:

#![no_std]
#![no_main]

use embassy_executor::Spawner;
use embassy_time::Timer;
use defmt::*;
use defmt_rtt as _;
use panic_probe as _;

#[embassy_executor::main]
async fn main(_spawner: Spawner) {
    let _p = embassy_stm32::init(Default::default());
    info!("Hello from Embassy!");

    loop {
        info!("tick");
        Timer::after_secs(1).await;
    }
}

If you see "Hello from Embassy!" and "tick" in your probe-rs output, your toolchain is working correctly.