Blink an LED - Embedded-rust Typing CST Test
Loading…
Blink an LED — Embedded-rust Code
Toggle an LED on pin 13 every 500 ms using Embedded Rust.
#![no_std]
#![no_main]
use panic_halt as _;
use cortex_m_rt::entry;
use stm32f4xx_hal::{prelude::*, stm32};
#[entry]
fn main() -> ! {
let dp = stm32::Peripherals::take().unwrap();
let gpiod = dp.GPIOD.split();
let mut led = gpiod.pd12.into_push_pull_output();
loop {
led.toggle().unwrap();
cortex_m::asm::delay(8_000_000);
}
}Embedded-rust Language Guide
Embedded Rust refers to using the Rust programming language to develop software for embedded systems, microcontrollers, and resource-constrained devices. It focuses on safety, performance, and concurrency without relying on runtime environments or garbage collection.
Primary Use Cases
- ▸Firmware development for microcontrollers
- ▸Real-time control of sensors and actuators
- ▸IoT device programming and communication
- ▸Embedded systems prototyping and development
- ▸Safety-critical and low-level hardware software
Notable Features
- ▸Memory safety without runtime overhead
- ▸Zero-cost abstractions and high performance
- ▸Strong type system preventing common bugs
- ▸Hardware-level control through HALs and PACs
- ▸Support for concurrency and async programming
Origin & Creator
Rust was created by Mozilla in 2010 to offer a safe, fast, and concurrent systems programming language. Embedded Rust emerged through the community’s adaptation of Rust for microcontroller and bare-metal programming.
Industrial Note
Embedded Rust is increasingly adopted in safety-critical industries such as automotive, aerospace, and industrial IoT for reliable, memory-safe firmware development.
Quick Explain
- ▸Rust provides memory safety without a garbage collector, making it ideal for embedded systems where reliability is critical.
- ▸Embedded Rust allows programming directly on microcontrollers and hardware with low-level control.
- ▸Supports concurrency and real-time programming through Rust's ownership and type system.
- ▸Integrates with hardware abstraction layers (HALs) and peripheral access crates (PACs) for device-specific programming.
- ▸Widely used in IoT, robotics, automotive, aerospace, and safety-critical embedded applications.
Core Features
- ▸Ownership and borrowing system ensures safe memory usage
- ▸No garbage collector, suitable for bare-metal systems
- ▸Embedded-friendly crates like `embedded-hal`, `cortex-m`, `rtic`
- ▸Support for no_std environments
- ▸Integration with Rust tooling (Cargo, rustfmt, Clippy)
Learning Path
- ▸Learn Rust basics: ownership, lifetimes, types, concurrency
- ▸Understand `no_std` and memory-constrained programming
- ▸Explore embedded HAL and PAC crates
- ▸Write small firmware for LEDs, buttons, and sensors
- ▸Advance to RTIC, concurrency, and IoT device development
Practical Examples
- ▸Blinking LED with no_std
- ▸Reading temperature and humidity sensors
- ▸Controlling servo motors or stepper motors
- ▸Implementing RTIC for concurrent tasks
- ▸UART, SPI, or I2C communication with peripherals
Comparisons
- ▸Embedded Rust vs C/C++: safer memory handling, modern tooling, zero-cost abstractions
- ▸Embedded Rust vs MicroPython: Rust is compiled, faster, and memory safe; MicroPython is interpreted and easier for rapid prototyping
- ▸Embedded Rust vs Arduino C: Rust offers concurrency safety and modern language features
- ▸Embedded Rust vs Go TinyGo: Rust has finer control over hardware and better real-time capabilities
- ▸Embedded Rust vs Zephyr RTOS C apps: Rust can run bare-metal or with RTOS, but benefits from memory safety and modern syntax
Strengths
- ▸Safe low-level programming with performance close to C/C++
- ▸Reduced risk of memory corruption and undefined behavior
- ▸Growing ecosystem for embedded hardware support
- ▸Concurrency and parallelism safety built into the language
- ▸Active community and modern tooling
Limitations
- ▸Learning curve for ownership, lifetimes, and concurrency models
- ▸Limited ecosystem compared to C/C++ in some niche hardware
- ▸Compile times can be longer than C/C++
- ▸Tooling for debugging embedded Rust is still maturing
- ▸Some microcontroller support requires nightly Rust features
When NOT to Use
- ▸When working with extremely resource-limited devices (<8KB flash) and Rust compilation overhead is unacceptable
- ▸For rapid prototyping where interpreted languages are faster to iterate
- ▸When existing C/C++ libraries are required without FFI adaptation
- ▸For legacy hardware with no Rust ecosystem support
- ▸When developer team has no Rust experience and timeline is strict
Cheat Sheet
- ▸cargo build --target <target> - compile for embedded target
- ▸cargo run - run on host for testing
- ▸#![no_std] - compile without standard library
- ▸#![no_main] - no standard main function, for embedded entry
- ▸cortex_m::asm::delay(n) - busy wait for n cycles
FAQ
- ▸Do I need a Rust license? -> No, Rust is open-source and free.
- ▸Can I use Embedded Rust on any microcontroller? -> Depends on target support and available HAL/PAC crates.
- ▸Is debugging harder in Embedded Rust? -> Slightly, but probe-rs and RTT tools help.
- ▸Does Rust perform well on microcontrollers? -> Yes, with zero-cost abstractions and careful memory management.
- ▸Can I use C libraries with Embedded Rust? -> Yes, via Rust FFI.
30-Day Skill Plan
- ▸Week 1: Rust syntax, ownership, and memory management
- ▸Week 2: Compile for `no_std`, learn HALs
- ▸Week 3: Flash and debug simple microcontroller projects
- ▸Week 4: Implement real-time tasks with RTIC
- ▸Week 5: Integrate communication peripherals and IoT features
Final Summary
- ▸Embedded Rust brings memory-safe, high-performance programming to microcontrollers and embedded systems.
- ▸Supports bare-metal, `no_std` development with modern tooling and concurrency safety.
- ▸Widely applicable in IoT, robotics, and safety-critical devices.
- ▸Integration with HALs, PACs, and RTIC frameworks enables reliable low-level firmware.
- ▸Growing ecosystem and community make it increasingly viable for production embedded development.
Project Structure
- ▸Cargo.toml - project configuration and dependencies
- ▸src/main.rs - main firmware entry point
- ▸src/lib.rs - optional library modules
- ▸boards/ or examples/ - board-specific code
- ▸Tests/ - unit tests, if supported on embedded targets
Monetization
- ▸Firmware consulting for embedded systems
- ▸IoT device development and prototyping
- ▸Industrial embedded systems development
- ▸Training courses on Embedded Rust
- ▸Custom embedded software solutions
Productivity Tips
- ▸Leverage HAL and PAC crates to reduce boilerplate
- ▸Use RTIC for predictable concurrency
- ▸Modularize code for multiple boards
- ▸Automate builds and flashing with Cargo
- ▸Document peripheral usage clearly
Basic Concepts
- ▸Ownership, borrowing, and lifetimes - memory safety concepts
- ▸no_std - building without standard library for embedded targets
- ▸HAL - hardware abstraction layer for peripherals
- ▸PAC - peripheral access crate for device registers
- ▸RTIC - real-time interrupt-driven concurrency framework