# Embedded Abstractions ## A Generic Peripheral Abstraction
--- ## The Full Rust "no-std" Stack
--- ## Micro Architecture Crate
Provides low-level access to CPU-specific features: interrupt handling, system timer, core registers. For RISC-V (ESP32-C3), this is the `riscv` crate. Not something you interact with directly in most application code, but it's the foundation everything else builds on. ```rust // Example: enabling interrupts at the CPU level unsafe { riscv::interrupt::enable() }; ```
--- ## The Peripheral Access Crate
Auto-generated from SVD files. A Rust representation of every register in the chip. Type-safe but low-level. You *can* use it directly, but you almost never need to. For ESP32-C3: the `esp32c3` crate. ```rust // PAC-level: writing directly to a register peripherals.GPIO.out_w1ts .write(|w| unsafe { w.bits(1 << 5) }); ```
--- ## The Hardware Abstraction Layer
Safe, ergonomic Rust APIs on top of the PAC. This is where we'll spend most of our time. For ESP32 chips: `esp-hal`. Provides the Instantiate → Configure → Control pattern for every peripheral. ```rust // HAL-level: safe, readable, type-checked let mut led = Output::new( peripherals.GPIO5, Level::Low, OutputConfig::default(), ); led.set_high(); ```
--- ## embedded-hal Traits
The key to portability. These traits define a standard interface that any HAL can implement. This is the contract between HALs and driver crates. ```rust // Works on ANY microcontroller fn blink( pin: &mut impl OutputPin, delay: &mut impl DelayNs, ) { pin.set_high().unwrap(); delay.delay_ms(500); pin.set_low().unwrap(); delay.delay_ms(500); } ```
--- ## Driver Crates
Built on top of `embedded-hal` traits. A driver crate provides a high-level API for a specific sensor or device. Ideally drivers would all use `embedded-hal` traits but they don't need to. A driver that does use the traits though, is what makes it hardware-agnostic. ```rust // This driver doesn't know about ESP32. // It just needs something that implements I2c. let mut imu = Icm42670::new( i2c, Address::Primary, ); let accel = imu.accel_norm().unwrap(); ```
--- ## Board Support Packages
The highest layer. Pre-configures everything for a specific board: pin assignments, peripheral setup, default configurations. Instead of remembering pin numbers, you use meaningful names. ```rust // Without BSP: let led = Output::new( peripherals.GPIO5, Level::Low, OutputConfig::default(), ); // With BSP: the board knows let led = board.led(); ```
The Embedded Rustacean · Rust Week 2026