Blog coding article

Knurling-rs changelog #29


Knurling-rs changelog #29

Published on 4 min read
Knurling icon
A tool set to develop embedded applications faster.
Details ❤️ Sponsor

    This is the 29th 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 🎉

    Call for feedback: Knurling User Survey

    We would love your feeback ❤️

    Please give us a few minutes of your time so we can get to know our users better. Help us shape Knurling by filling out this short survey.

    bitflags! support

    The PR defmt#528 by jonas adds support to print bitflags structs in defmt. It adds a macro that is a wrapper around the bitflags crate & provides a nearly identical interface with some limitations. For more information how to use the crate check its documentation.

    The new defmt::bitflags! imposes a few minor limitations compared with the underlying bitflags crate.

    • the macro only supports Rust's builtin unsigned types, custom types are not supported
    • when defining bitflags constants, you cannot refer to the Self type, use the struct identifier instead


    The example from the bitflags crate works with a minor modification:

    defmt::bitflags! {
       struct Flags: u32 {
           const A = 0b00000001;
           const B = 0b00000010;
           const C = 0b00000100;
           // Uses `Flags` instead of `Self`
           const ABC = Flags::A.bits | Flags::B.bits | Flags::C.bits;
    defmt::info!("Flags::ABC: {}", Flags::ABC);
    // "Flags::ABC: A | ABC | B | C"
    defmt::info!("Flags::empty(): {}", Flags::empty());
    // "Flags::empty(): (empty)"

    Fix test progress attribution

    Previously there was a small but annoying issue with attributing the test progress message with the test in question when using defmt-test. The defmt-test is a test harness to run unit tests on embedded devices. The generated progress output before the change was displaying the same source code location for all tests.

    For example assuming the following test suite:

    #[defmt_test::tests]   // line 6
    mod tests {
        use defmt::assert;
        fn first() {       // line 11
        fn second() {      // line 16

    The generated progress output would result in:

    $ cargo t -p testsuite
    0 INFO  (1/2) running `first`...
    └─ test::tests::__defmt_test_entry @ tests/
    1 INFO  (2/2) running `second`...
    └─ test::tests::__defmt_test_entry @ tests/
    2 INFO  all tests passed!
    └─ test::tests::__defmt_test_entry @ tests/

    where all tests were attributed to the same line. Thanks to jonas the PR 534 fixes the issue. The generated output now attributes the correct source code location for all tests.

    $ cargo t -p testsuite
    0 INFO  (1/2) running `first`...
    └─ test::tests::__defmt_test_entry @ tests/
    1 INFO  (2/2) running `second`...
    └─ test::tests::__defmt_test_entry @ tests/
    2 INFO  all tests passed!
    └─ test::tests::__defmt_test_entry @ tests/

    Add optional rzCOBS encoding+framing

    Thanks to Dirbaio defmt now supports rzcobs (Reverse Zerocompressing COBS) encoding to encode the stream. It is one big step to unblock future improvements.

    This new encoding has a few advantages. For one it reduces wire size. Wire streams that contain many zero bytes can also get compressed very fast by rzCOBS. The decoding part in probe-run is not implemented yet, but rzCOBS in defmt paves the way for that. Once it lands probe-run will support better resilience to corrupted streams or missing data. With added framing information it will be able to discard incomplete or corrupted frames (1 frame = 1 defmt log statement) and still be usable to decode the rest of the frames. As of now probe-run will stop as soon as it hits a corrupted frame & exit with an error.

    Improvements 🦀


    • #505 1/n Logger trait v2. Thanks to Dirbaio!
    • #527 Add logo & support text to introduction of defmt book.
    • #528 Add bitflags! support.
    • #529 Update user guide chapter in defmt book including visual improvements.
    • #535 Don't print leading wite space when timestamp absent.
    • #539 Add optional rzCOBS encoding + framing. Thanks to Dirbaio!

    Internal Improvements 🧽


    • #507 Remove code size costly optimizations. Thanks to Dirbaio!
    • #533 Add short description & link to Knurling User Survey to Readme.
    • #531 Refactor defmt-macros crate.
    • #534 Attribute test progress message to test in question in defmt-test.
    • #537 Remove :? display hint in qemu snapshot tests.
    • #538 Fix wrong bit count in comment. Thanks to Dirbaio!
    • #542 Add calls to test alternate hint for bitfields.
    • #549 Fix clippy warnings.
    • #551 Display git commit & date in defmt book.
    • #42 Add tests to check generation of memory.x in project root.


    • #244 Fix clippy warnings

    Fixes 🔨


    • #23 Add link to template code in e-paper chapter. Thanks to joemclo!

    Version Update Notification 🆙

    • probe-run v0.2.5

    Sponsor this work

    Knurling-rs 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!