Rust std on ThreadX - distribution 1
2026-08-02
I have a basic distribution for my Rust standard library port to ThreadX! Here is how to get the tooclhain for a thumbv7em-threadx-eabihf target. With that toolchain, you can compile std programs for simulated and real hardware.
What's supported?
This first toolchain supports
threadsynctimeallocstdio, implemented in external crates
I haven't thoroughly tested these things. And, if you try to use anything else in std, it will likely panic at runtime. This includes networking support.
Nevertheless, that's enough for the most-exciting things we do on microcontrollers: blink LEDs and print "hello world!" (And catch panic messages.)
Demos
Once you have a toolchain, here are some basic demos that run in / on
- QEMU
- a Teensy 4
- a NXP i.MX RT1170 EVK
The Teensy 4 demo periodically increments a number and prints it out:
use std::thread;
use std::time::Duration;
use rust_threadx_teensy4 as _;
fn main() {
let mut count = 0_usize;
loop {
thread::sleep(Duration::from_millis(500));
println!("Hello world! The count is {count}\r");
count = count.wrapping_add(1);
}
}It looks like a normal Rust program! There's no #[entry] macro on main, like we usually see in embedded programs. After some ThreadX setup, the standard library invokes your app's main() on a dedicated ThreadX thread. Although not shown in this example, you can spawn and join additional threads. (The QEMU example shows multiple threads, along with some basic sync primitives.)
There's much happening with the
use rust_threadx_teensy4 as _;If you run this on hardware, you'll also notice that the LED is blinking. That's a "feature" implemented by rust_threadx_teensy4. It shows how separate #[no_std] packages can use fusible to set up hardware and provide services. Of course, blinking an LED isn't a useful feature, but a whole USB device stack is a useful feature.
Indeed, rust_threadx_teensy4 also sets up a USB device stack that runs on another thread. The package implements the standard library's stdout using this thread, so your app can print things. All you have to do is include the package. The mechanisms deserve their own design docs / blog posts.
There's plenty that's strange. Just thinking about this example, including the things we're not showing:
- When
main()returns, your other threads keep running. That's not supposed to happen! - If you exceed your main thread's stack, you might not know it. We can use ThreadX stack checking logic, but I haven't turned that on.
- Your heap capacity is hard-coded in
std. It would be nice to have this configured outside ofstd, similar to externalstdioconfiguration. - You can't control the priority of your main thread, or any thread that you spawn. To do this, you'd need to work around
std. - See that
'\r'at the end ofprintln!? I'm a lazy driver implementer!
I won't be working on those things anytime soon. I have less than a month until I submit my RustConf slides, and a little more than a month until the conference. Let's see if I can get some basic networking support completed by then.