I’m happy to announce Release 0.3.0 of the little operating system that can, sometimes, but quite often randomly can’t. Yes, there are heisenbugs, but this release is too big not to get out of the door.

The biggest new feature is pre-emptive multithreading. Yes, we can now use the ‘default’ event-oriented model of previous releases, or a threaded model - or indeed combine the both (as we do in the updated example program).

In this release we have a scheduler for multithreading, with optional thread preemption if you nominate a suitably configured timer interrupt with a feature flag like pmt_tcb0_int in your config.toml - see the Rustdocs for further details - and a familiar interface for creating threads with avr_oxide::thread::spawn() and avr_oxide::thread::Builder.

To make this useful of course you need some thread synchronisation primitives; they’re provided in the avr_oxide::sync module with simple Mutex, EventWait and Arc implementations.

Oh, and of course all our high-level device drivers (including clocks, serial ports and buttons) now have blocking APIs that make use of our threading, in addition to the existing event-loop based APIs.

Other changes

Other changes include a focus on reducing the amount of memory used, both text and data segments. I’ve restructured the way the HAL exposes processor devices/pins to reduce memory use, and at the same time we now have board compatibility modules for boards other than Arduino devices - in particular, for ATmega XPlained evaluation boards - so you can easily code for these boards with things like onboard serial ports and hardware buttons accessed by aliases.

Memory management is also improved; instead of having to specify ‘small’, ‘medium’ or ’large’ memory model to size the heap, the heap will now automatically be sized to use all available memory. Now that we have multithreading, the stack size of every thread - including the main() thread - is of course now configurable as well.

Finally, there are also some tools for helping with debugging - error conditions in the OS can be indicated by pulse-codes on a nominated debug pin (which if you’ve enabled one of the board compatibility features will default to that board’s debug LED,) as well as output to the nominated panicout serial port (along with a full thread dump.) See the debug pin reference and thread dump format documentation for more information.

Further Reading