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 .text | Total image |
|---|---|---|
ESP-IDF C passive | 594 KiB | 849 KiB |
Rust no_std sniffer | 487 KiB | 634 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_stdRust 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.
-
esp-csi-rs, Binary size comparison: ESP-IDFpassivevs. Rustno_stdsniffer_wifi.specs/SIZE_DIFF_passive_vs_sniffer_wifi_exper.mdin the esp-csi-rs repository. ↩