Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

csi-rs

csi-rs is an umbrella project whose goal is to create an open, community-driven ecosystem composing libraries, tools, and documentation for channel state information (CSI) based projects and research in Rust. Currently, the focus is on making CSI data collection more accessible, convenient, and robust.

To that end, we are targeting cheap, low-power, and widely available devices to provide as low a barrier to entry as possible.

Why Rust?

The previous chapter described what CSI collection has historically cost: patched firmware, kernel modules, and a full Linux host. Espressif’s native CSI support removed most of that cost, which left a genuine question — if the platform is now a $3 microcontroller, what should the software on it be written in?

We choose Rust over C for several reasons.

Memory Safety (No Garbage Collector)

CSI collection is, structurally, an interrupt-driven system: the Wi-Fi driver hands you a borrowed buffer from a hot callback, and you have microseconds to decide what to do with it before it is reused. That is exactly the shape of problem that produces use-after-free and buffer-overrun bugs in C. Rust’s borrow checker makes the lifetime of that buffer part of the type, so the compiler rejects the mistake instead of the field deployment discovering it. None of this costs a runtime or a garbage collector, which a bare-metal device could not afford anyway.

Type and Thread Safety

A collection node is concurrent whether or not you wanted it to be. The radio callback, the traffic generator, the logging drain, and your own processing all run against shared state. Rust encodes “this value may cross a thread boundary” and “this value may be shared across threads” in the type system, so the compiler refuses to build a data race rather than leaving you to find it with an oscilloscope. In practice this is what lets esp-csi-rs offer a lock-free async delivery path and an inline callback path side by side without either one silently corrupting the other.

Zero-Cost Abstractions

The abstractions that make the API pleasant — typed node roles, configuration builders, iterators over subcarriers — compile away. This is measurable rather than aspirational. The crate’s own size study compares a Rust no_std sniffer against Espressif’s C passive CSI example on the same hardware:1

Build (speed-optimised)Flash .textTotal image
ESP-IDF C passive594 KiB849 KiB
Rust no_std sniffer487 KiB634 KiB

The Rust image is 25% smaller at the speed-optimised tier and 33% smaller when both are optimised for size — and even Rust’s max-speed build comes in 22% under the C build’s max-size build. The single largest contributor is simply not linking libstdc++ (~190 KiB), which a pure-C ESP-IDF build also avoids; the remainder is the runtime swap underneath (lwIP for smoltcp, FreeRTOS for esp-rtos). The point is not that Rust is magic, but that the safety above is not being paid for in flash.

These figures come from a specific pair of firmware images built for a specific chip, and the two applications are not feature-identical. Treat them as an order-of-magnitude answer to “does no_std Rust fit?”, not as a benchmark.

Superior Tooling and Debugging

cargo is the build system, the dependency manager, the test runner, and the documentation generator, and it is the same on every host OS. For embedded work specifically, the ESP Rust toolchain adds esp-generate for project scaffolding and espflash for flashing and monitoring, and defmt gives deferred, compact binary logging — which matters a great deal when the thing you are logging is a few hundred CSI samples arriving a hundred times a second.

Community Ecosystem

The crates this project stands on — esp-hal, esp-radio, esp-rtos, embassy — are actively maintained, open source, and shared with the rest of the embedded Rust world. csi-rs inherits their work rather than reimplementing it, and publishes to the same registry, so a CSI crate is installed exactly the way any other Rust dependency is.

Fun Fact, in 2024, the white house office of national cybersecurity published a report urging software developers to adopt memory-safe languages like Rust, and “stop” using unsafe languages such as C/C++.

Supported SoCs

Currently, csi-rs supports a variety of Espressif SoCs, with support for other SoCs in the works.


  1. esp-csi-rs, Binary size comparison: ESP-IDF passive vs. Rust no_std sniffer_wifi. specs/SIZE_DIFF_passive_vs_sniffer_wifi_exper.md in the esp-csi-rs repository.