0x55aa
← Back to Blog

Rust on Microcontrollers: From Web Dev to Embedded Systems 🦀🔌

9 min read

Rust on Microcontrollers: From Web Dev to Embedded Systems 🦀🔌

Hot take: If you can deploy to AWS, you can deploy to a $3 microcontroller! Rust makes embedded programming accessible to web developers like us - and it's actually FUN! 🎯

Coming from 7 years of Laravel and Node.js, my entire career was "server goes brrr, user gets JSON." The closest I got to hardware was SSHing into an EC2 instance. Memory constraints? Just scale vertically! Pointers? What are those?

Then my RF/SDR hobby got serious. I needed custom firmware for radio receivers, antenna controllers, and signal processors. The problem? Embedded C is terrifying. Segfaults in production? Bad. Segfaults on a satellite you can't debug? CATASTROPHIC! 🛰️

Enter Rust on embedded systems - and suddenly I could write microcontroller code with the same confidence as writing a Laravel controller! Let me show you why this is game-changing!

Wait, Rust Runs on WHAT? 🤯

Me, a web developer: "Rust needs what, 16MB to compile? How does it run on a chip with 32KB RAM?"

Rust: "Hold my crab emoji." 🦀

Here's the reality check: Rust compiles down to the SAME bare metal code as C. No runtime. No garbage collector. No Node.js event loop eating your precious kilobytes!

What you get:

  • Runs on chips with as little as 16KB RAM
  • Zero runtime overhead (unlike MicroPython/JavaScript)
  • Memory safety (unlike C/C++)
  • Same speed as C (but without the segfaults)
  • No operating system required (bare metal baby!)

Real talk: I'm running Rust on an STM32 microcontroller that costs less than my morning coffee and has less RAM than a single Chrome tab. And it's FAST! ⚡

Why Web Devs Should Care About Embedded 🎯

"But I write APIs, why do I need microcontrollers?"

Funny story - I thought the same thing! Then I discovered:

1. IoT is Everywhere

Your smart thermostat? Probably running embedded code. That USB security key? Embedded. Your car's dashboard? DEFINITELY embedded!

The opportunity: Companies are desperate for devs who understand BOTH web APIs AND hardware. That combo is RARE and VALUABLE! 💰

2. Performance Intuition

Writing for a chip with 32KB RAM teaches you things no bootcamp ever will:

  • Every byte matters
  • Allocation is expensive
  • Zero-copy is a lifestyle, not a pattern
  • "Just add a library" isn't an option when you have 16KB total!

Translation: You become a better web developer by understanding constraints!

3. It's Actually Similar to Web Dev

Think about it:

  • Embedded: Read sensor → Process data → Send to actuator
  • Web API: Read request → Process data → Send response

Same flow, different hardware! 🔄

The Learning Curve (Spoiler: Easier Than You Think) 📈

Coming from Laravel/Node.js, here's what surprised me:

What's Familiar ✅

Cargo still works:

# In web dev
cargo add tokio axum

# In embedded
cargo add cortex-m embedded-hal

Same tool, different targets!

Code looks the same:

// This looks like normal Rust!
let mut led = pins.pa5.into_push_pull_output();
led.set_high();  // Turn LED on

If you know Rust, you're 80% there!

What's Different (But Not Scary) 🆕

No standard library - You use #![no_std] instead

  • No Vec, String, HashMap (unless you bring your own allocator)
  • Think: PHP without Laravel helpers - raw but powerful!

You think in hardware:

  • "This pin is GPIO port A5"
  • "UART runs at 115200 baud"
  • "ADC samples at 1MHz"

Coming from web dev: Remember configuring nginx? Same energy! 🎵

My First Embedded Rust Project 🚀

For my RF hobby, I built an antenna rotator controller - a device that points my antenna at satellites.

The hardware:

  • STM32F103 "Blue Pill" board ($2 from AliExpress)
  • Stepper motor drivers
  • GPS module
  • OLED display

The code (simplified):

#![no_std]
#![no_main]

use cortex_m_rt::entry;
use stm32f1xx_hal::{pac, prelude::*};

#[entry]
fn main() -> ! {
    let dp = pac::Peripherals::take().unwrap();
    let mut gpioc = dp.GPIOC.split();
    let mut led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);

    loop {
        led.toggle();  // Blink LED
        cortex_m::asm::delay(8_000_000);  // Wait ~1 second
    }
}

What blew my mind:

  • Compiler caught my GPIO pin configuration errors at BUILD TIME
  • No null pointer exceptions possible
  • Type system prevented me from mixing up UART1 and UART2 pins
  • Same Rust I use for web APIs!

The Safety Story (This Is HUGE) 🛡️

Remember how Rust prevents data races in web apps? Same thing on hardware, but the stakes are HIGHER!

In C (the old way):

// Configure GPIO pin
GPIOA->MODER |= 0x01;  // Uh... what mode is that?
// Did I shift the right bits? WHO KNOWS! 🤷

In Rust:

// Configure GPIO pin
let mut pin = pins.pa5.into_push_pull_output();
// Type: PushPullOutput - compiler KNOWS what this pin can do!

Why this matters:

  • Can't use SPI pin as I2C (compiler error)
  • Can't read from an output pin (compiler error)
  • Can't access peripherals from multiple interrupts unsafely (compiler error)

Real example from my antenna controller: I tried to use a timer from both the main loop AND an interrupt handler. In C? Runtime crash. In Rust? Compiler error with suggestion to use a mutex! 🎯

Embedded Rust vs. Web Rust 🔄

Here's the mental model that clicked for me:

Web Rust (with std) Embedded Rust (no_std)
Vec<T> Fixed arrays [T; N]
String heapless::String<32>
println!() defmt::info!()
Tokio async embassy async
Error handling panic = restart chip!

The mindset shift: In web dev, we throw hardware at problems. In embedded, we solve problems with constraints! 🧠

Getting Started (The Practical Bits) 🛠️

What you need:

  1. Hardware ($5-20 to start):

    • STM32F103 "Blue Pill" (cheapest)
    • ESP32-C3 (WiFi + Rust!)
    • Raspberry Pi Pico (RP2040)
  2. Debugger ($3-10):

    • ST-Link V2 clone
    • Or use the built-in USB on some boards!
  3. Software (FREE):

    # Install embedded Rust
    rustup target add thumbv7m-none-eabi
    
    # Install flash tool
    cargo install probe-rs --features cli
    
    # Clone a template
    git clone https://github.com/rust-embedded/cortex-m-quickstart
    

Your first program:

# Build for ARM Cortex-M
cargo build --release

# Flash to chip (like deploying to production!)
probe-rs run --chip STM32F103C8

Coming from web dev: Think of probe-rs run as git push heroku main but for hardware! 🚀

Common "WTF" Moments (And Solutions) 😅

1. "Why is my binary so big??"

Problem: 500KB binary for blinking an LED?!

Solution:

[profile.release]
opt-level = "z"  # Optimize for size
lto = true       # Link-time optimization

Result: 2KB binary! (Smaller than this blog post!) 📦

2. "How do I debug without println!()?"

Web dev instinct:

println!("Debug: {}", value);  // ❌ Doesn't exist in no_std!

Embedded way:

defmt::info!("Debug: {}", value);  // ✅ Logs over debug probe!

Bonus: defmt compresses logs at compile time. Your "Request processed" string? Just 1 byte on the wire! 🔥

3. "Where's my stack trace?"

The truth: Embedded panics look like this:

panicked at 'index out of bounds'

The fix: Use probe-rs debugger - it's actually BETTER than web debugging:

  • Step through code
  • Inspect registers
  • Set breakpoints
  • No browser DevTools tab crashes! 😂

Real-World Embedded Rust 🌍

Who's using this?

  • Ferrous Systems: Automotive firmware
  • Oxide Computer: Server firmware
  • Amazon: Firecracker VMM
  • My RF projects: Antenna controllers, SDR firmware, signal processors

Why they chose Rust:

  • Memory safety (no recalls for buffer overflows!)
  • Performance (same as C)
  • Modern tooling (Cargo > Makefiles)
  • Fearless concurrency (even on bare metal!)

Should YOU Learn Embedded Rust? 🤔

Learn it if:

  • You want to understand how computers ACTUALLY work
  • IoT projects sound fun
  • You're tired of "it works on my machine" (try "it works on my chip!")
  • You have an RF/electronics hobby (like me!)
  • You want a skill that's rare and valuable

Maybe skip if:

  • You're still learning web Rust (get comfortable first!)
  • You have zero interest in hardware
  • You just want to build CRUD apps (totally valid!)

My take: Even if you never ship embedded code professionally, learning it makes you a 10x better systems thinker! 🧠

Resources to Get Started 📚

  • The Embedded Rust Book (free, excellent!)
  • Discovery Book (hands-on tutorials)
  • awesome-embedded-rust (GitHub repo)
  • embedded.fm podcast (not Rust-specific, but great!)

Community:

  • #embedded channel on Rust Discord (super helpful!)
  • embedded-wg on GitHub
  • Just ask - embedded Rust folks are NICE!

The Bottom Line 🎯

Coming from 7 years of Laravel/Node.js, I thought embedded programming was this arcane black magic reserved for electrical engineers. I was wrong!

Rust makes embedded accessible to web developers because:

  1. Same language - if you know Rust, you're halfway there
  2. Same tools - Cargo works everywhere
  3. Better safety - memory bugs caught at compile time
  4. Modern DX - no Makefiles, no weird IDE setup
  5. Active community - friendly and welcoming!

For my RF/SDR projects, Rust on microcontrollers means I can:

  • Write firmware faster than C
  • Debug issues at compile time, not runtime
  • Deploy with confidence (no memory leaks!)
  • Use modern language features (enums, traits, generics!)

The killer feature? I write ONE language for my entire signal processing pipeline:

  • Embedded Rust on the radio receiver hardware
  • Systems Rust for the SDR processing (gnuradio replacement)
  • Web Rust (Axum) for the control API
  • WASM Rust for the web interface

Same language. Different targets. Zero context switching! 🚀


Remember:

  1. Rust runs on $3 chips with 32KB RAM (seriously!)
  2. Same safety guarantees as desktop Rust (memory safe embedded!)
  3. Better DX than C (Cargo > Makefiles forever)
  4. Growing ecosystem (embedded-hal, embassy, probe-rs)
  5. Perfect for RF/SDR/IoT projects (my antenna controller proves it!)

Ready to flash some firmware? The hardware is cheaper than a pizza, and the skills are worth way more than a bootcamp certificate! 🦀✨


Want to connect? Find me on LinkedIn - always happy to chat about Rust, RF, or both!

Building something cool? Star my GitHub and share your embedded Rust projects!

Now go make some LEDs blink with memory safety! 🔌🦀