### In The Wild with 870 Active Installs
FREE RAG Converter Online -- <a href="https://RAGconverter.com">RAGconverter.com</a>
# rusty_rtos_port
[](https://github.com/remade-with-rust)
[](https://www.mata.network)
[](https://crates.io/crates/rusty_rtos_port)
[](https://docs.rs/rusty_rtos_port)
[](#license)
The architecture seam for Kairos: critical sections, the yield, the tick,
stack initialisation and the context switch. This is where the family keeps the
`unsafe` it cannot avoid, fenced into the smallest surface that can do the job.
- **The deterministic sim port** carries the whole of sim contract v1 and is
proven against the C Posix port by a trace diff at 100,000 ticks a scenario,
with `ulKairosExits` and `ulKairosYields` equal every time. **Zero `unsafe`
blocks.** A port that delivered a tick one critical-section exit early would
move every line after it, so the trace is the proof.
- **The silicon and host ports** — Cortex-M, RISC-V, Xtensa, and a host port on
OS threads — each with a QEMU or on-part kill test, and each poison-proven:
the test is re-run with the mechanism disabled and must FAIL.
**Known gaps.** No SMP and no MPU. The Xtensa port is the newest and its
context switch is proven from three frames deep rather than exhaustively.
- This package's plan: [docs/plans/rusty_rtos_port.md](https://github.com/Remade-With-Rust/rusty_rtos_port/blob/main/docs/plans/rusty_rtos_port.md)
- Every number: [docs/LEDGER.md](https://github.com/Remade-With-Rust/rusty_rtos_port/blob/main/docs/LEDGER.md)
- The family plan: Kairos [`docs/plans/rtos-mission.md`](https://github.com/Remade-With-Rust/kairos/blob/main/docs/plans/rtos-mission.md)
**Claims discipline:** this README makes no performance or capability claim that
is not backed by a test, a benchmark ledger entry, or a kill test recorded in
the plan. "Scaffold" means scaffold. "Sim only" means the sim port; "builds, not
flashed" means no chip has run it.
## Kill tests
A port is the one place where "it compiles" means least, so every backend
carries a test that fails when the mechanism is removed.
| sim | 8,408,764 trace lines identical to the C Posix port across nine scenarios | a tick delivered one exit early moves every later line |
| Cortex-M | `PendSV` switch on QEMU `mps2-an385`; preemption cell | — |
| Cortex-M tickless | **401 SysTick interrupts -> 0** with the schedule digest unmoved | ✅ removing the pended-last-tick line fails the tick band |
| Xtensa tickless | **400 alarm interrupts -> 0 on a real XIAO S3**, digest unmoved | ✅ the clock gate catches a drifting tick the digest cannot |
| RISC-V | 201 switches between two tasks that never yield, zero faults | — |
| Xtensa | 100/99 resumptions from three frames deep on a XIAO S3, zero faults | ✅ |
| host | a task that NEVER yields is still taken off the CPU: 40 of 40 expected laps | ✅ **1 of 120** with `KAIROS_HOST_NO_PREEMPT=1` |
**A defect this found, and it is the kind that only a kill test finds.** The
RISC-V `switch_context` resumed with `ret`, so the first preemptive switch was
also the last. The port gained `switch_context_trap` and
`new_task_context_preemptive`, and the cell now runs 201 switches with zero
faults.
**Another, on Cortex-M:** `exit_critical` *enabled* interrupts instead of
restoring them, so a task became schedulable before it had a stack and faulted
to `pc = 0` three hundred and sixty ticks later, in a different task. Three
probes came back clean first — because the cell had no `HardFault` handler, so
a faulting task presented as the whole system stopping.
**Still open:** the Unix backend of the host port freezes a thread by signalling
it to park itself, because Unix has no call that stops another thread from
outside; the Windows backend uses `SuspendThread` directly.
## Using it
Pick a backend crate and hand the kernel a port. The trait is small on purpose
— everything architecture-shaped is one of these methods.
```rust
use rusty_rtos_core::port::Port;
/// A port the kernel can drive. `COMMITS_SWITCH` is the one that bites:
/// it tells the kernel whether the port takes the switch itself.
#[derive(Debug, Default)]
struct MyPort;
impl Port for MyPort {
/// `true` for every port that owns stacks. Left `false`, the kernel
/// treats itself as STACKLESS and moves `current` inside `port_yield`
/// — and a port that then switches again makes two selections per
/// yield, which on a ready list of two is the same task for ever.
const COMMITS_SWITCH: bool = true;
fn yield_now(&self) { /* pend the switching exception */ }
fn enter_critical(&self) { /* mask */ }
fn exit_critical(&self) { /* RESTORE, never unconditionally enable */ }
fn set_interrupt_mask_from_isr(&self) -> u32 { 0 }
fn clear_interrupt_mask_from_isr(&self, _saved: u32) {}
fn in_isr(&self) -> bool { false }
fn set_in_tick_entry(&self, _yes: bool) {}
}
```
Both comments above are defects this family actually shipped and fixed; they
are in the trait's own docs for the same reason.
## Performance
| FreeRTOS `xPortPendSVHandler` | 19 |
| Kairos `PendSV` | **19** |
| FreeRTOS | 83 | 1.00× |
| Kairos | **74** | **1.12× cheaper** |
Method: both arms counted in their own sections so the boundary is exact, not
sampled. The RISC-V cooperative row reads 2.77× cheaper and should **not** be
quoted as a win — see the kernel crate's README for why the ARM control is what
makes it readable.
```sh
bench/switch-cost/run.sh # from the Kairos umbrella
```
## Tickless idle, and why the two ports do it differently
Both implement `Port::suppress_ticks_and_sleep`; the mechanisms are not
interchangeable, and the difference is architectural rather than stylistic.
| the sleep | `wfi` — **leaves PRIMASK alone**, so the tick is left *pending* and never taken | `waiti 0` — **sets `PS.INTLEVEL` to zero and leaves it there**, so the tick really is taken, and the caller's critical section is gone from the wake onward |
| suppressing the tick | clear the pending exception (`ICSR.PENDSTCLR`) | a flag read at the top of the handler, plus re-raising the mask the instant `waiti` returns |
| where the code lives | in this crate, beside the SysTick register map — SysTick is a **core** peripheral | in the firmware cell — `SYSTIMER` is a **chip** peripheral belonging to `esp-hal`, and this crate is HAL-free |
**Two laws both ports obey, each paid for.**
* **Sleep to a tick boundary, or drive the tick from an absolute grid — never
restart a period on waking.** Restarting discards whatever fraction of a
period had elapsed while the application ran, every sleep, and it compounds:
measured at **0.99 % slow, 38.7 seconds in an hour**, with a flawless logical
tick count.
* **Measure the sleep; do not trust it.** `esp-hal`'s own documentation warns
that a refused, a rejected and a very short `Rtc::sleep_light` are
indistinguishable from its return. Both ports read elapsed time off a
free-running counter, which is also what lets the sleep underneath be
swapped for a deeper one without re-proving anything.
## Backends
| `rusty_rtos_port-core` | any | the trait and the sim port, zero `unsafe` |
| `rusty_rtos_port-cortex-m` | `thumbv7m-none-eabi`+ | QEMU-proven, corpus 18/18; **tickless** |
| `rusty_rtos_port-riscv` | `riscv32imac-unknown-none-elf` | QEMU-proven, preemptive path fixed and measured |
| `rusty_rtos_port-xtensa` | `xtensa-esp32s3-none-elf` | **on silicon**, XIAO ESP32-S3; kernel on a tick, **tickless** |
| `rusty_rtos_port-host` | x86-64 Windows + Linux | OS threads, one run permit; `SuspendThread` / `SIGUSR1` |
## Layout
```text
crates/rusty_rtos_port facade: re-exports + prelude; the crate you depend on
crates/rusty_rtos_port-core no_std (+ alloc); forbid(unsafe); types, traits, algorithms
firmware/ per-chip example projects, excluded from the workspace
docs/plans/ this package's plan and its hardening audit
docs/LEDGER.md every number, with its method line
```
## Build
```sh
cargo test --workspace # host: the tests
cargo check -p rusty_rtos_port-core --no-default-features \
--target thumbv7em-none-eabihf # Cortex-M4F class, no alloc
cargo check -p rusty_rtos_port-core --no-default-features --features alloc \
--target riscv32imac-unknown-none-elf # ESP32-C6 class, with alloc
```
CI holds the core to `thumbv7em-none-eabihf`, `thumbv8m.main-none-eabihf`,
`riscv32imac-unknown-none-elf` and `riscv32imafc-unknown-none-elf`, with and
without `alloc`, plus `cargo deny check`. Firmware examples (Xtensa needs the
esp toolchain; Cortex-M and RISC-V work on stable) are built from their own
directories under `firmware/`.
## Security
The **[threat model](docs/threat-model.md)** states what this unit protects,
who it protects it from, and the **residual risks it does not cover**, each
with an owner, a review date and the condition that closes it. Every `unsafe`
in the family's ports is written up in **[UNSAFE.md](UNSAFE.md)**, and CI fails
if one is not (`tools/unsafe_census.py`).
Two are worth knowing before you adopt it:
- **The stack builders are `unsafe fn`s, and the window each writes is its
contract.** `rusty_rtos_port-cortex-m::init_stack` was a safe `fn` through
0.2.1, which was unsound; it is `unsafe` from 0.3.0. `fuzz/task_stacks`
checks every builder writes nothing outside its documented window.
- **A deleted task's saved registers are not wiped.** The ports never log or
move register state, but a firmware handling key material must zeroize its
own buffers rather than rely on a dead task's stack being cleared.
## Part of Remade With Rust
This crate is part of **[Kairos](https://github.com/Remade-With-Rust/kairos)** —
FreeRTOS remade in memory-safe Rust, as independent packages that expose the API
a FreeRTOS developer already knows and prove every scheduling decision against
the C kernel's own trace. `rusty_rtos_port` is the seam between it and the metal.
**Where this sits for Mata.** Kairos is the real-time layer on the device
itself, and [`rusty_rtos_mqtt`](https://crates.io/crates/rusty_rtos_mqtt) is the way out of it.
Paired with the **MATA distributed cloud**, robotics and sensor data has two
routes — read it on the machine, or reach it through the cloud — with the same
memory-safe crates at both ends.
The family:
[`rusty_rtos_core`](https://crates.io/crates/rusty_rtos_core) (the shared vocabulary),
[`rusty_rtos_kernel`](https://crates.io/crates/rusty_rtos_kernel) (the scheduler),
[`rusty_rtos_port`](https://crates.io/crates/rusty_rtos_port) (the architecture seam),
[`rusty_rtos_heap`](https://crates.io/crates/rusty_rtos_heap) (the allocators),
[`rusty_rtos_json`](https://crates.io/crates/rusty_rtos_json) (coreJSON),
[`rusty_rtos_sntp`](https://crates.io/crates/rusty_rtos_sntp) (coreSNTP),
[`rusty_rtos_mqtt`](https://crates.io/crates/rusty_rtos_mqtt) (coreMQTT),
[`rusty_rtos_backoff`](https://crates.io/crates/rusty_rtos_backoff) (backoffAlgorithm),
[`rusty_rtos-capi`](https://crates.io/crates/rusty_rtos-capi) (the C ABI) and
[`rusty_rtos_demo`](https://crates.io/crates/rusty_rtos_demo) (the conformance corpus).
All ten are on crates.io. Also check out
the rest of **[github.com/remade-with-rust](https://github.com/remade-with-rust)**.
## About Mata Network
**[Mata Network](https://www.mata.network/)** builds sovereign, self-hostable
privacy infrastructure — *"stop sacrificing your privacy for convenience"*:
wallet & identity, a password manager, a contact manager, and a browser
extension that stops your information leaking as you browse.
**Remade With Rust** is our open-source home for the permissively-licensed
building blocks that work depends on — including
[remade_ffmpeg_rs](https://github.com/Remade-With-Rust/remade_ffmpeg_rs) (the
FFmpeg alternative) and [FFAI](https://github.com/Remade-With-Rust/FFAI) (the
AI media toolkit).
→ **[www.mata.network](https://www.mata.network/)**
## License
MIT OR Apache-2.0, at your option. FreeRTOS is MIT-licensed by Amazon.com,
Inc. or its affiliates; this crate remakes its API and behaviour from the
published sources and links no FreeRTOS code.
---
## Hardening status
**Tier** critical-path · **Audited** 2026-10-01 (deep) · **v1.0.0 gates** 14/16 · [Full checklist](docs/plans/use-protection-please.md)
`█████████████████░░░` **88%** · 30 Completed · 0 Scheduled · 4 Incomplete · 21 N/A
| 0 — Threat modeling | 2 | 0 | 0 | 0 |
| 1 — Toolchain | 3 | 0 | 0 | 1 |
| 2 — Supply chain | 7 | 0 | 1 | 0 |
| 3 — Code level | 7 | 0 | 0 | 0 |
| 4 — Static analysis | 1 | 0 | 0 | 0 |
| 5 — Dynamic analysis | 3 | 0 | 0 | 0 |
| 6 — Fuzzing and properties | 3 | 0 | 1 | 0 |
| 7 — Formal verification | 0 | 0 | 1 | 0 |
| 8 — Build and binary | 0 | 0 | 0 | 2 |
| 9 — Runtime privilege | 0 | 0 | 0 | 1 |
| 10 — Cryptography | 0 | 0 | 0 | 3 |
| 11 — CI/CD, release, and operations | 4 | 0 | 1 | 0 |
| 12 — Compliance controls | 0 | 0 | 0 | 14 |
| **Total** | **30** | **0** | **4** | **21** |
**Architect** — [Tim Almond](https://github.com/Ttimmahlax) — accountable for this unit's security design; rendered