This is a rewrite of the RTIC framework with a focus on modularity, cleaner application syntax and ease of hardware ports. It supports most single-core Cortex-M and RISC-V MCUs as well as the dual-core RP2040.
The following distributions are maintained by the RTI D027 CX team/organization:
| Distribution | Target | Link | Cargo |
|---|---|---|---|
rticx-cortex-m |
Single-core Cortex-M (armv6-m, armv7-m and above) | https://github.com/rticx-rs/rticx/tree/main/distributions/rticx-cortex-m | cargo add rticx-cortex-m |
rticx-riscv |
Single-core RISC-V (generic SLIC interrupt controller, ESP32-C3, ESP32-C6) | https://github.com/rticx-rs/rticx-riscv | cargo add rticx-riscv |
rticx-rp2040 |
Raspberry Pi Pico / RP2040 (dual-core Cortex-M0+) | https://github.com/rticx-rs/rticx-rp2040 | cargo add rticx-rp2040 |
The RTIC syntax has been simplified:
#[rticx_cortex_m::app(device = stm32f0::stm32f0x0, dispatchers = [TIM6])]
mod app {
#[shared]
struct Shared {
counter: u32,
}
#[init]
fn system_init() -> (Shared, TaskInits) {
/* start SysTick */
(Shared { counter: 0 }, TaskInits { tick: Tick { ticks : 0 } })
}
/// Hardware task, runs on every SysTick interrupt
#[task(binds = SysTick, priority = 1, shared = [counter])]
struct Tick {
ticks: u32;
}
impl RticTask for Tick {
fn exec(&mut self) {
self.ticks+=1;
let _ = Worker::spawn(self.ticks);
}
}
/// Async task, can await timers/channels, locks shared state deadlock-free
#[async_task(priority = 2, shared = [counter], init = generated)]
struct Worker;
impl RticAsyncTask for Worker {
type SpawnInput = u32;
async fn exec(&mut self, ticks: u32) {
self.shared().counter.lock(|c| *c += ticks);
}
}
}See the framework in action in ~2 minutes, no hardware needed.
# Prereqs: qemu-system-arm and the two Cortex-M Rust targets
sudo apt-get install -y qemu-system-arm
rustup target add thumbv7m-none-eabi thumbv6m-none-eabi
make qemu-armv7mRTIC is one of the best embedded Rust frameworks offering exceptional guarantees such as deadlock-free execution and blazing-fast scheduling thanks to SRP and hardware-offloaded scheduling. However, its monolithic architecture is showing its limits and is becoming increasingly hard to contribute to, extend and maintain.
RTICX keeps the guarantees and breaks the monolith:
- A small core (
rticx-core) captures only the SRP Tasks/Resources model, making it ideal for certifications and security reviews. - Compilation passes are independent crates that transform and expand user syntax (software tasks, async/await, etc.) which users can opt-in/out from.
- Distributions are target-specific crates that implement backend traits,
register the passes they want, and expose the final
#[app]macro.
The payoff: new hardware ports (including multicore) and new syntax features no longer require forking the framework or understanding its entire codebase.
On top of the original RTIC framework, RTICX adds:
- Single-binary multicore support: extended syntax and hardware support for single-firmware multicore platforms like the RP2040.
- Simplified, more idiomatic Rust syntax: less magic, cleaner code, same functionality.
- Choice of software task flavors: RTICv1-style lightweight tasks (no async) or RTICv2-style async/await tasks.
- Easier hardware ports and contributions: new ports and syntax extensions don't require forking the framework nor fully understanding how it works. See the distributor guide in the project wiki.
rticx-expand: a debug tool that expands any RTICX application into fully executable source (for GDB debugging, security vetting, etc.).
And, just like the original RTIC framework:
- Tasks as the unit of concurrency: interrupt-driven (hardware tasks) or spawned on demand (lightweight software tasks, async/await tasks).
- Message passing between tasks at spawn time.
- A timer queue: async tasks can delay or schedule themselves for future execution, enabling periodic tasks.
- Preemptive multitasking through task priorities.
- Data-race-free memory sharing through fine-grained, priority-based critical sections.
- Deadlock-free execution guaranteed at compile time, stronger than
the standard
Mutexabstraction. - Minimal scheduling overhead: the hardware does the bulk of the scheduling.
- Highly efficient memory usage: all tasks share a single call stack, with no hard dependency on a dynamic memory allocator.
- All Cortex-M devices supported (BASEPRI on armv7+, source masking on armv6-m) and most RISC-V microcontrollers (any SLIC-based MCU, plus ESP32-C3 / ESP32-C6).
- A task model amenable to known WCET and scheduling analysis techniques.
Full user and distributor guides are available in the project wiki.
Pick a distribution for your target, add its #[app] macro to your
crate, and write tasks. The User Guide
walks you through getting started,
the full syntax, and debugging.
The RTICv2 to RTICX Migration Guide doubles as a step by step guide and an LLM skill. Point your favorite LLM at it (or load it as the rticv2-to-rticx-migration skill) to have the bulk of the port done for you.
Want to run RTICX on new hardware, or extend the syntax? Distributions and compilation passes are ordinary crates, no fork needed. The Distributor Guide covers writing distributions and writing compilation passes.
See Distributor Guide: Architecture
- ARM Cortex-M playground: SysTick hw task + spawned sw task + SRP lock
- ARM Cortex-M playground: Async and Monotonics example
- ARM Cortex-M playground: Async Priority 0 tasks
- RISC-V playground: Async Ping Pong
- RP2040 multicore ping-pong
- RTICv2 examples migrated to RTICX
See COMPATIBILITY.md.
RTICX has been actively used in academic research since its early experimental days. Its modular architecture makes porting to new hardware and custom SoCs straightforward, and lets researchers experiment with exotic syntax extensions without modifying the core, or even fully understanding how it works.
| Distribution | Target | Link |
|---|---|---|
rticx-hippo |
Single-core RISC-V Hippomenes MCU | https://github.com/rticx-rs/rticx-hippo |
rticx-atalanta |
Single-core RISC-V Atalanta MCU | https://github.com/rticx-rs/rticx-atalanta |
While RTICX is a from-scratch rewrite of RTIC's macro and core logic, several parts of this repository and other repositories in this organization, notably the hardware exports and target backends in the cortex-m and riscv distributions and all community examples, have been backported from the upstream RTIC codebase. Many thanks to the RTIC community; a large share of the credit for these parts goes to its maintainers and contributors.