Skip to content

Update the book #921

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jan 27, 2025
1 change: 1 addition & 0 deletions book/src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
50 changes: 50 additions & 0 deletions book/src/defmt-versions.md
Original file line number Diff line number Diff line change
@@ -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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are no legal obligations by stating that, are there?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's check on Zulip.


## 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`.
81 changes: 81 additions & 0 deletions book/src/introduction.md
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about making that a separate page?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm afraid I don't have the context for this comment. Making what a separate page?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah sorry, I meant the components. Adding it as components.md just after the introduction.

Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading