defmt is an efficient logging framework. Just like log, the defmt crate enables defmt::info, defmt::warn and other levels. It also has a defmt::println! macro.
The name defmt comes from deferred formatting:
(…) instead of formatting
255u8into"255"and sending the string, the single-byte binary data is sent to a second machine, the host, and the formatting happens there.
So the formatting is deferred to the host. The other bit improving efficiency is compression:
defmt’s string compression consists of building a table of string literals, like"Hello, world"or"The answer is {:?}", at compile time. At runtime the logging machine sends indices instead of complete strings.
Source: defmt docs.
defmt Ecosystem
esp-println, esp-backtrace and espflash provide mechanisms to use defmt:
-
espflashhas support for different logging formats, one of them beingdefmt. -
esp-printlnneedsdefmt-espflashfeature. As their docs state:Using the
defmt-espflashfeature,esp-printlnwill install adefmtglobal logger. Updated theCargo.toml’s features. -
esp-backtraceneeds adefmtfeature that usesdefmtlogging to print panic and exception handler messages.
Exercise
Go to exercises/defmt directory.
-
Update the runner’s logger in
.cargo/config.toml:[target.riscv32imac-unknown-none-elf] - runner = "espflash flash --monitor" + runner = "espflash flash --monitor -L defmt"so that
espflashmonitor can decode the format of thedefmtmessages received. -
Update
Cargo.tomlto include the needed features:esp-println = { version = "0.16.0", features = [ "esp32c6", - "log-04", + "defmt-espflash", ] } # (...) esp-backtrace = { version = "0.18.0", features = [ "esp32c6", "panic-handler", + "defmt", ]} -
Due to the linking process we need to add
defmtlinker script tocargo/config.toml:rustflags = [ # .... + "-C", "link-arg=-Tdefmt.x", ] -
Add defmt to the dependencies.
-
Logging level: Use the
defmt::println!and some defmt macros to print a few messages.-
When building the app, set
DEFMT_LOGlevel as done forESP_LOGearlier. -
An alternative to changing
.cargo/config.tomlis usingDEFMT_LOG=<value> cargo run --release; the same is valid forESP_LOG.
-
-
Add a
panic!macro to trigger a panic with adefmtmessage.
exercises/defmt/examples/defmt.rs contains a solution. You can run it with the following command: cargo run --example defmt --release. You will need to have the settings above done correctly though!
Suggested reading
Short articles that give more context:
- defmt linking process for setting the compilation-time linker up
- defmt DEFMT_LOG environment variable
- esp-println logging formats