关于 embedded-rust
面向 Agent 的嵌入式 Rust 固件开发指南,涵盖项目配置、烧录、调试、日志、并发和 panic 处理。内容结合 probe-rs、defmt、RTIC 与 no_std 配置流程。
主要功能
- 01配置 no_std 固件
- 02使用 probe-rs 烧录和调试
- 03添加 defmt 结构化日志
- 04用 RTIC 实现中断驱动并发
- 05选择 panic 处理器
适用场景
- 01向 MCU 烧录固件
- 02调试嵌入式 Rust 程序
- 03通过调试探针输出精简日志
- 04处理 no_std 固件中的并发与 panic
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mohitmishra786/ low-level-dev-skills --skill embedded-rust安装后在 Claude Code 中输入/embedded-rust确认已加载。
附带文件references/embedded-rust-targets.md
详细介绍
嵌入式 Rust
用途
指导 Agent 进行嵌入式 Rust 开发:使用 probe-rs/cargo-embed 烧录和调试、使用 defmt 进行结构化日志记录、使用 RTIC 并发框架、使用 cortex-m-rt 启动、配置 no_std,以及选择 panic 处理程序。
触发条件
- “如何将我的 Rust 固件烧录到 MCU?”
- “如何调试我的嵌入式 Rust 程序?”
- “如何在嵌入式 Rust 中使用 defmt 进行日志记录?”
- “如何使用 RTIC 实现中断驱动的并发?”
- “对于嵌入式 Rust,#![no_std] #![no_main] 是什么意思?”
- “如何处理 no_std 嵌入式 Rust 中的 panic?”
工作流
1. 项目设置
# Cargo.toml
[package]
name = "my-firmware"
version = "0.1.0"
edition = "2021"
[dependencies]
cortex-m = { version = "0.7", features = ["critical-section-single-core"] }
cortex-m-rt = "0.7"
defmt = "0.3"
defmt-rtt = "0.4"
panic-probe = { version = "0.3", features = ["print-defmt"] }
# Embassy (async embedded) — alternative to RTIC
# embassy-executor = { version = "0.5", features = ["arch-cortex-m"] }
[profile.release]
opt-level = "s" # size optimization for embedded
lto = true
codegen-units = 1
debug = true # keep debug info for defmt/probe-rs
# .cargo/config.toml
[build]
target = "thumbv7em-none-eabihf" # Cortex-M4F / M7
[target.thumbv7em-none-eabihf]
runner = "probe-rs run --chip STM32F411CEUx" # auto-run after build
rustflags = ["-C", "link-arg=-Tlink.x"] # cortex-m-rt linker script
2. 最小裸机程序
// src/main.rs
#![no_std]
#![no_main]
use cortex_m_rt::entry;
use defmt::info;
use defmt_rtt as _; // RTT transport for defmt
use panic_probe as _; // panic handler that prints via defmt
#[entry]
fn main() -> ! {
info!("Booting up!");
// Access peripherals via PAC or HAL
let _core = cortex_m::Peripherals::take().unwrap();
// let dp = stm32f4xx_hal::pac::Peripherals::take().unwrap();
loop {
info!("Running...");
cortex_m::asm::delay(8_000_000); // rough delay
}
}
常见 MCU 的目标三元组:
| MCU 系列 | 目标三元组 |
|---|---|
| Cortex-M0/M0+ | thumbv6m-none-eabi |
| Cortex-M3 | thumbv7m-none-eabi |
| Cortex-M4(无 FPU) | thumbv7em-none-eabi |
| Cortex-M4F / M7 | thumbv7em-none-eabihf |
| Cortex-M33 | thumbv8m.main-none-eabihf |
| RISC-V RV32IMAC | riscv32imac-unknown-none-elf |
rustup target add thumbv7em-none-eabihf
3. probe-rs — 烧录和调试
# Install probe-rs
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/probe-rs/probe-rs/releases/latest/download/probe-rs-tools-installer.sh | sh
# Flash firmware
probe-rs run --chip STM32F411CEUx target/thumbv7em-none-eabihf/release/firmware
# Interactive debug session
probe-rs debug --chip STM32F411CEUx target/thumbv7em-none-eabihf/release/firmware
# List connected probes
probe-rs list
# Supported chips
probe-rs chip list | grep STM32
使用 cargo:
# Using the runner in .cargo/config.toml
cargo run --release # builds, flashes, and streams defmt logs
cargo build --release # build only
4. defmt — 高效日志记录
defmt(反格式化器)会将日志字符串编码为整数,传输最少字节,并在主机端解码:
use defmt::{info, warn, error, debug, trace, Format};
// Basic logging
info!("Temperature: {} °C", temp);
warn!("Stack usage: {}/{}", used, total);
error!("I2C error: {:?}", err);
// Derive Format for custom types
#[derive(Format)]
struct Packet { id: u8, len: u16 }
info!("Received: {:?}", pkt);
// Assertions (panic with defmt message)
defmt::assert_eq!(result, expected);
defmt::assert!(condition, "message with {}", value);
defmt 后端(选择一个):
# RTT (fastest, needs debug probe connected)
defmt-rtt = "0.4"
# Semihosting (slower, works without RTT support)
defmt-semihosting = "0.1"
5. RTIC — 实时中断驱动并发
// Cargo.toml
// rtic = { version = "2", features = ["thumbv7-backend"] }
#[rtic::app(device = stm32f4xx_hal::pac, peripherals = true, dispatchers = [SPI1])]
mod app {
use stm32f4xx_hal::{pac, prelude::*};
use defmt::info;
#[shared]
struct Shared {
counter: u32,
}
#[local]
struct Local {}
#[init]
fn init(cx: init::Context) -> (Shared, Local) {
info!("RTIC init");
periodic_task::spawn().unwrap();
(Shared { counter: 0 }, Local {})
}
#[task(shared = [counter])]
async fn periodic_task(mut cx: periodic_task::Context) {
loop {
cx.shared.counter.lock(|c| *c += 1);
info!("Count: {}", cx.shared.counter.lock(|c| *c));
rtic_monotonics::systick::Systick::delay(500.millis()).await;
}
}
#[task(binds = EXTI0, local = [], priority = 2)]
fn button_isr(cx: button_isr::Context) {
info!("Button pressed!");
}
}
6. Panic 处理程序
| Crate | 行为 | 适用场景 |
|---|---|---|
panic-halt | 无限循环 | 生产环境,无调试探针 |
panic-probe | defmt 消息 + 停止 | 使用 probe-rs 进行开发 |
panic-semihosting | GDB 半主机输出 | 使用 GDB 进行开发 |
panic-reset | 硬复位 | 看门狗式恢复 |
# Choose exactly one panic handler
[dependencies]
panic-halt = "0.2" # or:
panic-probe = { version = "0.3", features = ["print-defmt"] }
嵌入式 Rust 目标三元组参考,请参阅 references/embedded-rust-targets.md。
相关技能
- 使用
skills/embedded/openocd-jtag,了解基于 OpenOCD、可替代 probe-rs 的调试方式 - 使用
skills/rust/rust-no-std,了解#![no_std]的模式和限制 - 使用
skills/embedded/linker-scripts配置内存布局 - 使用
skills/rust/rust-cross设置交叉编译工具链
评论
支持 Markdown