一键导入
rust-no-std
Rust no_std skill for embedded and bare-metal development. Use when writing
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Rust no_std skill for embedded and bare-metal development. Use when writing
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
C++20 modules skill for modern C++ projects. Use when working with named modules, module partitions, header units, CMake MODULE_SOURCES, Clang -fmodules-ts, BMI caching issues, or migrating from headers to modules. Activates on queries about C++20 modules, import statements, module interface units, header units, or BMI files.
FreeRTOS skill for embedded RTOS development. Use when creating tasks, managing priorities, using queues and mutexes, detecting stack overflows, configuring FreeRTOS via FreeRTOSConfig.h, or debugging FreeRTOS applications with OpenOCD and GDB. Activates on queries about FreeRTOS tasks, queues, semaphores, mutexes, configASSERT, stack overflow, vTaskDelay, or FreeRTOS-aware debugging.
C++20 coroutines skill for understanding coroutine mechanics and debugging. Use when working with co_await, co_yield, co_return, implementing promise_type, understanding coroutine frame layout, debugging suspended coroutines in GDB, or inspecting frame allocation with Compiler Explorer. Activates on queries about C++20 coroutines, co_await, co_yield, promise_type, coroutine_handle, coroutine suspension, or coroutine frame.
eBPF skill for Linux observability and networking. Use when writing eBPF programs with libbpf or bpftrace, attaching kprobes/tracepoints/XDP hooks, debugging verifier errors, working with eBPF maps, or achieving CO-RE portability across kernel versions. Activates on queries about eBPF, bpftool, bpftrace, XDP programs, libbpf, verifier errors, eBPF maps, or kernel tracing with BPF.
Binary hardening skill for security-hardened C/C++ builds. Use when enabling RELRO, PIE, stack canaries, FORTIFY_SOURCE, CFI sanitizers, shadow stack, or seccomp-bpf syscall filtering. Covers checksec analysis, compiler and linker flags for hardened builds, and NSA/CISA-recommended mitigations. Activates on queries about binary hardening, checksec, RELRO, PIE, stack canaries, FORTIFY_SOURCE, CFI, shadow stack, or seccomp.
WebAssembly runtime skill using wasmtime. Use when running WASM modules with wasmtime CLI, working with WASI preview2, using the component model, embedding wasmtime in Rust applications, limiting execution with fuel metering, or debugging WASM with DWARF in wasmtime. Activates on queries about wasmtime, WASI, WASM component model, wasmtime embedding, WIT interfaces, fuel metering, or server-side WebAssembly.
| name | rust-no-std |
| description | Rust no_std skill for embedded and bare-metal development. Use when writing |
Guide agents through #![no_std] Rust development: what core and alloc provide vs std, implementing custom global allocators, panic handler selection for embedded targets, and strategies for testing no_std crates on the host machine.
// src/lib.rs
#![no_std]
// core is always available (no OS needed)
use core::fmt;
use core::mem;
use core::slice;
// alloc: heap collections — requires a global allocator
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "alloc")]
use alloc::{vec::Vec, string::String, boxed::Box, format};
pub fn add(a: u32, b: u32) -> u32 {
a + b
}
# Cargo.toml
[features]
default = []
alloc = [] # opt-in to heap allocation
[dependencies]
# no_std-compatible dependencies only
| Crate | Requires OS | Requires heap | Provides |
|---|---|---|---|
core | No | No | Primitives, traits, iter, fmt, mem, ptr, slice, option, result |
alloc | No | Yes (allocator) | Vec, String, Box, Arc, Rc, HashMap (requires global allocator) |
std | Yes | Yes | All of core + alloc + OS APIs (threads, files, sockets, env) |
std re-exports everything in core and alloc, so use std::fmt and use core::fmt are equivalent when std is available.
What's available in core only (no heap, no OS):
// These work in no_std:
core::fmt::Write // trait for write! macro
core::iter // iterators
core::ops // operators (+, -, *, Deref, etc.)
core::option::Option
core::result::Result
core::mem::{size_of, align_of, swap, replace}
core::ptr::{read, write, null, NonNull}
core::slice, core::str
core::sync::atomic // atomic types
core::cell::{Cell, UnsafeCell, RefCell}
core::cmp, core::convert, core::clone, core::default
core::num // numeric conversions
core::panic::PanicInfo // for panic handler
To use alloc crate in no_std, provide a global allocator:
// src/allocator.rs — embedded allocator using linked_list_allocator
use linked_list_allocator::LockedHeap;
#[global_allocator]
static ALLOCATOR: LockedHeap = LockedHeap::empty();
pub fn init_heap(heap_start: usize, heap_size: usize) {
unsafe {
ALLOCATOR.lock().init(heap_start as *mut u8, heap_size);
}
}
[dependencies]
linked-list-allocator = { version = "0.10", default-features = false }
// src/main.rs (bare-metal)
#![no_std]
#![no_main]
extern crate alloc;
use alloc::vec::Vec;
mod allocator;
// In init code (after BSS/data init):
allocator::init_heap(0x20010000, 0x10000); // 64KB heap at RAM+64KB
// Now alloc types work:
let mut v: Vec<u32> = Vec::new();
v.push(42);
Common embedded allocator crates:
linked-list-allocator: general purpose, no_stdbuddy-alloc: power-of-two buddy systemdlmalloc: port of Doug Lea's malloctalc: fast, suited for embeddedIn no_std, you must provide a panic handler — Rust requires one:
// Option 1: halt on panic (simplest, production)
use core::panic::PanicInfo;
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop {} // spin forever
}
// Option 2: print panic info via defmt (embedded with debug probe)
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
defmt::error!("{}", defmt::Display2Format(info));
cortex_m::asm::udf(); // undefined instruction → hard fault
}
// Option 3: use a panic crate (in Cargo.toml)
// panic-halt = "0.2" — spin loop
// panic-reset = "0.1.1" — reset MCU
// panic-probe = "0.3" — defmt + probe-rs
Design your library to work with and without alloc:
#![no_std]
#[cfg(feature = "alloc")]
extern crate alloc;
pub struct Parser<'a> {
data: &'a [u8], // borrowed slice: no allocation needed
pos: usize,
}
impl<'a> Parser<'a> {
pub fn new(data: &'a [u8]) -> Self {
Parser { data, pos: 0 }
}
// Core API: return borrowed data, no allocation
pub fn next_token(&mut self) -> Option<&'a [u8]> { /* ... */ None }
// Alloc API: only when alloc feature is enabled
#[cfg(feature = "alloc")]
pub fn collect_all(&mut self) -> alloc::vec::Vec<&'a [u8]> {
let mut tokens = alloc::vec::Vec::new();
while let Some(tok) = self.next_token() {
tokens.push(tok);
}
tokens
}
}
# Cargo.toml
[dev-dependencies]
std = [] # allow std in tests only (via cfg)
[features]
std = []
// lib.rs
#![cfg_attr(not(test), no_std)] // no_std except during tests
// Tests compile normally with std — only library code is no_std
Or use a separate test harness:
# Run tests targeting the host (std available for test framework)
cargo test --target x86_64-unknown-linux-gnu
# Test with the actual embedded target using QEMU
cargo test --target thumbv7em-none-eabihf # fails: no test runner on bare metal
# Solution: use defmt-test or probe-run for on-target testing
# Or: architecture-neutral pure logic tests on host
# Check no_std compliance without hardware
cargo check --target thumbv7em-none-eabihf
cargo build --target thumbv7em-none-eabihf
skills/embedded/embedded-rust for probe-rs, defmt, and RTIC with no_stdskills/rust/rust-cross for cross-compilation target setupskills/rust/rust-unsafe for unsafe patterns needed in allocator implementationsskills/embedded/linker-scripts for heap region placement in bare-metal targets