Menambahkan Rust sebagai senjata kedua: memahami no_std tanpa OS, memory safety tanpa garbage collector, ownership yang mencegah race condition, serta ekosistem embedded-hal dan cargo-embed, ditutup praktik aplikasi embedded Rust pertama yang aman dan idiomatik

Di episode 1 kalian sudah mendengar ramalannya: Rust mainstream untuk embedded. Kini tibalah waktunya membuktikannya. Rust menawarkan apa yang selama puluhan tahun menjadi mimpi firmware engineer: memory safety saat compile time, tanpa biaya runtime. Bug yang di C/C++ butuh debugging berminggu-minggu — buffer overflow, use-after-free, race condition — di Rust dicegah oleh compiler sebelum binary lahir.
Tentu ada trade-off: kurva belajar ownership yang curam dan ekosistem yang masih berkembang. Tapi di 2026, toolchain embedded Rust (embassy, esp-hal, stm32-hal) sudah matang untuk produksi — dari keyboard mekanik sampai aerospace. Episode ini membangun fondasinya.
Embedded Rust bekerja dalam dua mode. Untuk MCU kecil, targetnya no_std — Rust tanpa standard library, karena std membutuhkan OS dan heap global:
| Aspek | std | no_std |
|---|---|---|
| Memakai heap | Global allocator default | Harus manual (opsional) |
| Thread/OS | Threads bawaan | Bare-metal atau RTOS |
| Kapan dipakai | Host, Linux, aplikasi besar | MCU, driver, kernel |
| Contoh | Desktop app | STM32/ESP32 firmware |
Ciri no_std dalam kode: #![no_std] di crate root dan atribut #![no_main] untuk entry point tanpa runtime. Semua kode yang memakai std (file I/O, thread, String) harus ditulis ulang dengan alternatif embedded — alloc crate, fixed-size buffers, dan pattern heapless.
Kekuatan inti Rust adalah ownership: setiap data punya satu pemilik, dan saat pemilik dihapus, data dihapus. Dua aturan yang mengubah segalanya:
Dampaknya pada embedded: race condition yang di C memerlukan disiplin manual (episode 8), di Rust tidak bisa di-compile. Contoh — berbagi data antara ISR dan task adalah pola paling rawan di C:
#![no_std]
#![no_main]
use cortex_m::interrupt::Mutex;
use cortex_m_rt::entry;
use core::cell::Cell;
static TICK: Mutex<Cell<u32>> = Mutex::new(Cell::new(0));
#[interrupt]
fn SysTick() {
cortex_m::interrupt::free(|cs| {
TICK.borrow(cs).set(TICK.borrow(cs).get() + 1);
});
}
#[entry]
fn main() -> ! {
loop {
let now = cortex_m::interrupt::free(|cs| TICK.borrow(cs).get());
if now % 1000 == 0 {
toggle_led();
}
}
}Mutex di cortex-m (bukan mutex thread) adalah cara Rust memaksa akses aman ke data yang dibagi ISR: compiler memastikan hanya lewat critical section yang tepat data itu disentuh. Data race = compile error, bukan bug yang menunggu di lapangan.
Ekosistem embedded Rust dibangun di atas embedded-hal — trait abstrak untuk GPIO, I2C, SPI, dan UART. Selama chip memiliki implementasi embedded-hal, kode driver kalian portable: driver yang ditulis untuk sensor bisa dipakai di STM32, ESP32, RP2040, dan nRF tanpa mengubah satu baris pun.
Toolchain untuk embedded Rust:
| Tool | Fungsi |
|---|---|
cargo + thumbv7em-none-eabihf target | Compile ke ARM Cortex-M |
cargo-embed / probe-rs | Flash + debug via debug probe |
defmt | Logging format minimal dengan overhead kecil |
embassy | Async runtime embedded modern (alternatif RTOS) |
Setup singkat:
rustup target add thumbv7em-none-eabihf # STM32F4
cargo install probe-rs-tools
cargo init --bin my-firmwareUntuk flash dan debug langsung:
cargo embed --releaseProject minimal dengan cortex-m + embedded-hal untuk STM32:
[dependencies]
cortex-m = "0.7"
cortex-m-rt = "0.7"
panic-halt = "0.2"
embedded-hal = "1.0"
stm32f4xx-hal = { version = "0.18", features = ["stm32f401"] }#![no_std]
#![no_main]
use cortex_m_rt::entry;
use embedded_hal::digital::OutputPin;
use stm32f4xx_hal::{pac, prelude::*};
#[entry]
fn main() -> ! {
let dp = pac::Peripherals::take().unwrap();
let rcc = dp.RCC.constrain();
let clocks = rcc.cfgr.sysclk(84.MHz()).freeze();
let gpioc = dp.GPIOC.split();
let mut led = gpioc.pc13.into_push_pull_output();
loop {
led.set_high().ok();
cortex_m::asm::delay(2_000_000);
led.set_low().ok();
cortex_m::asm::delay(2_000_000);
}
}Perhatikan: tidak ada unsafe, tidak ada global variable, tidak ada memset manual. Pin LED dibungkus tipe PushPullOutput — compiler tidak mengizinkan memakainya sebagai input, jadi kesalahan konfigurasi pin tercegah di type system.
Note
Jangan panik dengan kurva belajar. Kalian tidak perlu "berpindah" dari C — kalian menambah senjata. Strategi terbaik: tulis modul kecil yang aman (driver, state machine) dalam Rust sementara sistem tetap C, atau sebaliknya. Banyak tim produksi di 2026 justru memakai keduanya: C untuk legacy dan driver chip-level, Rust untuk logika aplikasi yang paling rawan bug.
std tanpa sadar — Rust di MCU wajib no_std; compiler akan menolak banyak crate biasa.thumbv7em-none-eabihf untuk Cortex-M4F; arsitektur lain beda target.Cell, Mutex, dan static mut adalah bahasa baru yang butuh latihan.Inti yang harus dibawa pulang:
no_std adalah mode Rust untuk MCU — tanpa OS, tanpa heap default.embedded-hal membuat driver portable antar chip; probe-rs/cargo-embed untuk flash & debug.Di episode 12 selanjutnya kita menghubungkan perangkat ke dunia: communication & networking embedded — TCP/IP stack, MQTT, dan secure communication, dengan praktik membuat perangkat terhubung. Dunia yang kalian pelajari di episode 1 — "hampir semua perangkat terhubung" — sekarang kita wujudkan. Sampai jumpa di episode 12!