Blog coding article

Knurling-rs changelog #13


Knurling-rs changelog #13

Published on 3 min read
Open Source Project
Knurling icon
A tool set to develop embedded applications faster.
Details ❤️ Sponsor

    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!


    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 and Display2Format 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 the consts module has been removed.


      defmt::info!("{}", Debug2Format::<consts::U8>(&Some(1234)));
      // Output is truncated to 8 Bytes:
      // Some(123


      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 use defmt::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.


      fn timestamp() -> u64 {
          static COUNT: AtomicUsize = AtomicUsize::new(0);
          COUNT.fetch_add(1, Ordering::Relaxed) as u64


      static COUNT: AtomicUsize = AtomicUsize::new(0);
      defmt::timestamp!("{=usize}", COUNT.fetch_add(1, Ordering::Relaxed));



    • #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



    • #334 Fix dead link in parser docs
    • #342 Fix a data corruption issue when using bools in write!

    Version Update Notification

    We've published the initial version of the defmt-print tool to It can be used with defmt 0.1.

    Internal Improvements


    • #324 Fixed Clippy lints
    • #329 Document safety of implementation detail functions
    • #331 Add more compile-fail tests
    • #333 Hide Formatter's inner field
    • #339 Make leb64 encoding fully safe (while at the same time reducing its code footprint)


    • #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!