// the find
knurling-rs/defmt
Efficient, deferred formatting for logging on embedded systems
defmt is a logging framework for microcontrollers that does the heavy lifting on-device by sending compact binary frames over RTT/ITM/semihosting, then decoding them on the host. Format strings get interned at compile time into the ELF symbol table, so you transmit an index and raw bytes instead of formatted ASCII. It's aimed at anyone doing serious embedded Rust work where every byte of flash and every cycle of CPU time matters.
Format string interning is the key trick here — strings live in the ELF, not in flash, so a `defmt::info!("temperature: {}", temp)` costs almost nothing on-device. The transport layer is pluggable (RTT, ITM, semihosting) and the host-side decoder is a proper library you can embed in your own tooling, not just a CLI black box. The defmt-test framework for running tests on actual hardware via QEMU is genuinely useful and not something you get with most embedded logging setups. Maintained by Ferrous Systems with a real book, semver checks in CI, and UI test coverage for macro error messages.
The split between on-device and host-side decoding means you must keep the ELF binary in sync with whatever is capturing the log frames — if you flash a new binary and forget to update the decoder's ELF reference, you get garbage. There's no built-in solution for structured log aggregation or shipping logs somewhere useful in production; this is firmly a development-time tool. The global logger trait requires unsafe impl blocks and careful attention to re-entrancy and preemption, which the docs explain but still trip people up. No_std-only, so if your project ever grows a std component that also needs logging, you're duct-taping defmt to the log crate via an adapter.