This is the third 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!
It has been a while since our last changelog and a lot has happened since then!
Highlights
-
We have passed 100 sponsors on GitHub sponsors! 🎉 We want to thank each and everyone of them for supporting our work on Knurling!
-
We have launched the knurling website ✨. The website gives you an overview of all the projects under the Knurling umbrella.
- We have published the first version of
flip-linkon crates.io.flip-linkis a linker wrapper that adds zero-cost stack overflow protection to embedded Rust programs.flip-linkis set as the default linker in our application template.
New features
We want to give the community a round of applause 👏 for submitting several PRs these last few weeks and a special shoutout to @Dirbaio 🏅 for authoring all the PRs in this section!
- #198
defmtnow supports formatting 64-bit integers
- #197
defmtlog messages can now include the@character. If you are wondering why this didn't work before, the reason is that log messages are stored in the ELF's symbol table as symbols. The@character is special in symbol names; the text after the@is treated as the symbol version; this made reconstructing the whole message tricky. The@character is now escaped to prevent it from adding a version the symbol.
- #200
defmtnow supports formatting thestrtype. Note thatintern!-ing string literals should be preferred as that saves bandwidth butstrsupport is required to usederive(Format)onstructs andenums that contain strings (&str).
- #201
defmtnow supports formatting heap-allocated types likeBoxandRc. Note that this support is behind an opt-in Cargo feature named "alloc".
- #203
defmtnow supports formatting tuples of up to 12 elements. Why 12? To follow the long standing tradition set by the standard library.
Improvements
- #184 enhance
defmt's bitfield compression. When you log a bitfield view of a register like ininfo!("M: {:8..12}, E: {:15..16}", u32_val), now 1 byte of register data is transmitted, instead of 2 bytes (this included the Least Significant Byte which is not printed / formatted).
Fixes
- #77 in non-
defmtmodeprobe-runnow flushes data to stdout more often. Before it would only flush data on newline causing, for example, the first print statement inrprint!("hello"); sleep(5.seconds()); rprintln!("world!")to not be printed until the second one was executed.
- #204
defmt's ELF parser now skips empty symbol names before parsing them. This increases our compatibility with GNU tools likeobjcopy, which sometimes inject empty symbol names when used to post-process ELF files produced byrustc.
- #178
defmt'sderive(Format)macro now generates trait bounds like the built-inderive(Debug)macro. Before we were using a more precise way to generate trait bounds but this appears to not be widely used in the ecosystem because we ran into compiler bugs so we decided to switch to the more widely used approach. The difference between the two approaches is pictured below.
#[derive(Format)]
struct S<a, T> { inner: &'a Option<T> }
// expansion of `derive` using previous approach
impl<a, T> Format for S<'a, T>
where
&'a Option<T>: Format // <- bound on field type
{ /* .. */ }
// expansion of `derive` using current approach (same as `Debug`)
impl<a, T> Format for S<'a, T>
where
T: Format // <- bound on input type parameter
{ /* .. */ }
Internal improvements
We are working hard towards a first crates.io release of defmt so that you won't need to juggle
several git dependencies in your projects. Most PRs in this section are work towards that goal.
- #190 prevent using multiple versions of
defmt. Oncedefmtis on crates.io it'll be possible to use e.g. v0.1 and v0.2 in the same application (Cargo allows this). The encoder and decoder don't support mixing ABI incompatible logs in the same stream (the stream will appear to be corrupted) sodefmtwill give you a compiler error if you run into this scenario.
- #196 extend
probe-runversion check to support crates.io releases.probe-runchecks that itsdefmtdecoder supports thedefmtversion used in the target application. That check relied solely on git hashes but crates.io release won't have that git information so the check has been extended to consider the crate version.
-
#197 remove a small implementation detail crate. For the first release of
defmtwe won't be stabilizing the crates that sit betweendefmtandprobe-run– these include things like thedefmtstream decoder and other ELF parsing utilities – so we are trying to reduce the number of those crates (which will also need to be published on crates.io). -
#202 mark unstable API as such in the API documentation. This refers to the crates between
defmtandprobe-run. Thedefmtcrate won't have any unstable API on its first release.
- #175, #192, #193, #194, #195 use JSON to encode the log messages stored in the ELF symbol table. This has be done with extensibility in mind: it should let users attach custom-metadata to log messages in the future. It also helped implement PR #197.
Sponsor this work
probe-run and defmt are Knurling projects and can be funded through GitHub
sponsors. Sponsors get early access to the tools we are building. Thank
you to all of the people already sponsoring our work through the Knurling project!