This is the 13th changelog for Knurling-rs, our push to sustainably build better tooling for developing and debugging Rust software for embedded systems. Knurling-rs includes a suite of tools that make it easier to develop, log, debug, and test your embedded Rust libraries and applications!
Knurling-rs is supported by our sponsors on GitHub. If you're interested in seeing more projects like this, consider becoming a sponsor today!
Highlights
We've added several new crates to the defmt repository that make it easier to write custom infrastructure for it.
defmt-itm
allows transferring defmt log frames over the ITM peripheral (Instrumentation Trace Macrocell) and capture them on the SWO pin. This uses less RAM than defmt-rtt
and can be faster.
defmt-print
is a command-line tool that decodes defmt frames. This allows building flexible data pipelines for defmt, instead of having to use probe-run
. It can be used as follows:
$ cat defmt-frames | defmt-print -e path/to/firmware.elf
We've also been hard at work implementing new defmt 0.2 features:
-
#340 makes
Debug2Format
andDisplay2Format
stream the data instead of formatting to a fixed buffer. This makes these adapters easier to use and consume much less stack space. Users no longer have to specify a buffer size, so theconsts
module has been removed.Before:
defmt::info!("{}", Debug2Format::<consts::U8>(&Some(1234))); // Output is truncated to 8 Bytes: // Some(123
After:
defmt::info!("{}", Debug2Format(&Some(1234))); // Output is not truncated: // Some(1234)
-
#343 allows full customization of the defmt timestamp that is attached to each message. The
#[defmt::timestamp]
attribute has been changed to a regular macro that works just like the logging macros. You can now usedefmt::timestamp!("{=u32:µs}", get_time())
to define what timestamp data is transferred and how it is displayed. This works with arbitrary format strings, so you can display CPU cycles or time since reset, real-world time, a counter, or anything else.Before:
#[defmt::timestamp] fn timestamp() -> u64 { static COUNT: AtomicUsize = AtomicUsize::new(0); COUNT.fetch_add(1, Ordering::Relaxed) as u64 }
After:
static COUNT: AtomicUsize = AtomicUsize::new(0); defmt::timestamp!("{=usize}", COUNT.fetch_add(1, Ordering::Relaxed));
Improvements
defmt
- #327
impl<T> Format for PhantomData<T>
- #332 Improve
Format
trait docs - #335 Add the defmt-itm crate
- #337 Improve diagnostics on double
write!
- #338 Add defmt-logger and defmt-print crates
- #340 Streaming
core::fmt
adapters - #343 Customizable timestamps
Fixes
defmt
Version Update Notification
We've published the initial version of the defmt-print
tool to crates.io. It can be used with defmt 0.1.
Internal Improvements
defmt
- #324 Fixed Clippy lints
- #329 Document safety of implementation detail functions
- #331 Add more compile-fail tests
- #333 Hide
Formatter
'sinner
field - #339 Make leb64 encoding fully safe (while at the same time reducing its code footprint)
probe-run
- #132 Make use of the new defmt-logger crate
Sponsor this work
Knurling is mainly funded through GitHub sponsors. Sponsors get early access to the tools we are building and help us to support and grow the knurling tools and courses. Thank you to all of the people already sponsoring our work through the Knurling project!