diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index a9c05014..7807c434 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -20,6 +20,7 @@ - [JSON output](./json-output.md) - [Migrating from `v0.2.x` to `v0.3.0`](./migration-02-03.md) - [Design & impl details](./design.md) + - [Defmt Versions](./defmt-versions.md) - [Interning](./interning.md) - [Dealing with duplicates](./duplicates.md) - [Logging levels](./linker-sections.md) diff --git a/book/src/defmt-versions.md b/book/src/defmt-versions.md new file mode 100644 index 00000000..10382bd1 --- /dev/null +++ b/book/src/defmt-versions.md @@ -0,0 +1,50 @@ +# Defmt Versions + +Any given version of the `defmt` crate will implement one specific *Defmt +Version* - also known as the *wire format version*. Because a compilation can +only use one version of the `defmt` crate, each compilation will use a +consistent *Defmt Version*. + +**Note**: Changing the *Defmt Version* used in the `defmt` crate will be a minor version change (e.g. from 1.0.0 to 1.1.0). If you wish to remain on a specific *Defmt Version* for compatibility with older versions of `defmt-decoder` and `defmt-print`, you should pin your `defmt` crate to a specific release. + +The *Defmt Version* used in any given ELF file is expressed using a symbol (listed below). + +The `defmt-decoder` crate supports multiple *Defmt Version* values, and so can +work with newer and older firmware. + +This is a list of *Defmt Version* values and what they mean. + +## Defmt Version 4 + +- Supported by defmt-decoder versions: 0.3.6 onwards +- Supported by defmt-print versions: 0.3.6 onwards +- Supported by defmt versions: 0.3.4 onwards +- Symbol name: `_defmt_version_ = 4` +- Interned strings are JSON, with fields: + - `package`: the name of the package (as defined in `Cargo.toml`) that emitted the log + - `tag`: one of `defmt_prim`, `defmt_fmt`, `defmt_str`, `defmt_trace`, `defmt_debug`, `defmt_info`, `defmt_warn`, or `defmt_error` + - `data`: the format string + - `disambiguator`: a unique random number + - `crate_name`: the crate that emitted the log (might not be the package name if this is a binary within a package) +- Supported encodings: + - RZCOBS: noted by presence of the symbol `_defmt_encoding_ = rzcobs` + - RAW: noted by presence of the symbol `_defmt_encoding_ = raw` +- Withdrawal notice: This version will be supported in new releases of the `defmt-decoder` and `defmt-print` crates for at least the next 24 months, on a rolling basis. Notice will be given here when that 24 month period begins. + +## Defmt Version 3 + +- First stable wire format (before that we used crate versions / git hashes) +- Supported by defmt versions: 0.3.0 to 0.3.3 +- Interned strings are JSON, with fields: + - `package`: the name of the package (as defined in `Cargo.toml`) that emitted the log + - `tag`: one of `defmt_prim`, `defmt_fmt`, `defmt_str`, `defmt_trace`, `defmt_debug`, `defmt_info`, `defmt_warn`, or `defmt_error` + - `data`: the format string + - `disambiguator`: a unique random number +- Symbol name: `_defmt_version_ = 3` +- Withdrawal notice: This version will be supported in new releases of the `defmt-decoder` and `defmt-print` crates for at least the next 12 months, on a rolling basis. Notice will be given here when that 12 month period begins. + +## PUA Defmt Versions + +We have set-aside a range of Defmt Versions for private use. We guarantee that no official version of the defmt tools will use these versions, so you can unambiguously use them to add customised features to your private forks of defmt. + +The reserved versions are `_defmt_version_ = 1000` through to `_defmt_version_ = 1999`. diff --git a/book/src/introduction.md b/book/src/introduction.md index 83ebca40..b2a04393 100644 --- a/book/src/introduction.md +++ b/book/src/introduction.md @@ -34,6 +34,87 @@ That is, instead of formatting `255u8` into `"255"` and sending the string, the `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. +## Components + +Fundamentally, `defmt` is comprised of multiple packages - some run on your microcontroller :pager:, some run on your host machine :computer:, and some are macros that generate code (for either of those scenarios) :construction:. + +### [`defmt`](https://crates.io/crates/defmt) 📟 + +The `defmt` crate runs on your microcontroller or other target device. It +exports macros, like `info!` that libraries can use to emit logging messages, +and the `#[no_mangle]` infrastructure those macros use to send log messages to +the registered logging transport. + +The `defmt` crate requires a *transport* to be registered within your firmware. +Example transports include `defmt-rtt` and `defmt-itm`. The transport is handed +a *log frame* every time a line of code like `defmt::info!("...")` is executed. +That *log frame* describes which interned format string to use, and what arguments +to print with it. + +### [`defmt-rtt`](https://crates.io/crates/defmt-rtt) 📟 + +This library is a *logging transport* for `defmt` that sends data over +SEGGER's RTT transport protocol. + +This is a good choice when using `probe-rs` because support is built-in to that +runner. + +### [`defmt-itm`](https://crates.io/crates/defmt-itm) 📟 + +This library is a *logging transport* for defmt that sends data over +Arm's Instruction Trace Macrocell. + +This might be a good choice if you are using a commercial debugger with ITM +support but not RTT support. + +### [`defmt-semihosting`](https://crates.io/crates/defmt-semihosting) 📟 + +This library is a *logging transport* for defmt that sends data over +*semihosting* calls (i.e. breakpoints that wake up your debugger). + +You should only use this when running firmware inside QEMU, because otherwise +it's very slow. + +### [`defmt-test`](https://crates.io/crates/defmt-test) 📟 + +This library is for running unit tests with our deprecated runner `probe-run`. +You might want to look at [`embedded-test`], which integrates a bit better with +`probe-rs`. + +[`embedded-test`]: https://crates.io/crates/embedded-test + +### [`panic-probe`](https://crates.io/crates/panic-probe) 📟 + +This library can be added to an Embedded Rust application to provide an +implementation of `#[panic_handler]`. It can optionally route the +`core::panic::PanicInfo` structure over RTT (using the `rtt_target` crate) or +over defmt (using the `defmt` crate). + +### [`defmt-decoder`](https://crates.io/crates/defmt-decoder) 🖥️ + +The `defmt-decoder` library turns *log frames* into human-readable Unicode text. +The popular `probe-rs` runner uses this library to decode `defmt` log frames +emitted by your firmware. + +### [`defmt-parser`](https://crates.io/crates/defmt-parser) 🖥️ + +This library turns defmt log frames into Rust structures. You probably want to +use `defmt-decoder` instead, which actually decodes the log frames instead of +just parsing them. + +### [`defmt-print`](https://crates.io/crates/defmt-print) 🖥️ + +The `defmt-print` CLI program uses `defmt-decoder` to turn `defmt` log frames into +human-readable Unicode text. You can use this if your log frames aren't coming +via `probe-rs` but instead come in through some other mechanism (e.g. a network +connection). + +### [`defmt-macros`](https:///crates.io/crates/defmt-macros) 🚧 + +This crate contains the procedural macros used and/or exported by the `defmt` +crate. It is an internal implementation detail and should be not used +standalone. + ## Support `defmt` is part of the [Knurling] project, [Ferrous Systems]' effort at