1. Overview

Copyright (c) 2026 Muhammad Anisur Rahman. All rights reserved.

What TUWA-RTOS is

A preemptive real-time operating system. A portable kernel provides task scheduling, memory management, timers and a full set of inter-task communication primitives; a thin per-CPU port and a per-board support package sit under it.

  your application  +  your BSP      <- per BOARD    (source, you write this)
  ----------------------------------------------------------
  TUWA-RTOS kernel                        <- per CPU      (supplied, binary)

You write the board support package and the application. Everything above the BSP seam is supplied and needs no changes to bring TUWA-RTOS up on new hardware.

The three things you interact with

What it isWhere it is documented
The APIThe calls your application makes into TUWA-RTOS.05-api-reference.md
The BSP seamThe functions YOUR board code must define, which TUWA-RTOS calls.04-bsp-guide.md
The module loaderLoading relocatable binaries at run time.06-modules.md
The shellBrowsing the filesystem and loading modules by hand.05-api-reference.md

Supported targets

TargetToolchainModule formatStatus
AArch64aarch64-none-elf-gccELF .soBoots, schedules preemptively, mounts a filesystem, loads and runs a real gcc shared object from it, shell works
x86-64 (UEFI)mingw-w64 gccPE .dllSame, with a real mingw DLL
RISC-V 64riscv-none-elf-gccpicfmt2 .twaSame, with a picfmt2 module
i386 (UEFI)gcc -m32picfmt2 .twaSame, with a picfmt2 module

All four are equivalent. Nothing is supported on one target and missing on another.

Each is verified by booting the real kernel under QEMU and running its self-tests. Reference board support packages for all four are supplied, and 02-build-guide.md gives the exact command for each.

Other architectures exist in the source tree at varying stages and are not part of this release. Do not infer support from a directory name.

Preemption is off until your BSP turns it on

TUWA-RTOS starts cooperative. Your BSP enables preemption explicitly, in UserOsConfig():

int UserOsConfig(void)
{
    EnablePreemption();
    return 1;
}

This is the single most common bring-up mistake. Without that call the system runs, tasks start, the tick fires and nothing ever preempts - which presents as "the scheduler is broken" when in fact it was never switched on. It is the BSP's decision because only the board knows whether its timer and interrupt controller are ready to be preempted on.

Verifying a build

Every reference BSP boots, runs its self-tests and prints its results. Three lines matter:

ALL-SCHEDULABLE-TASKS-RAN     the scheduler preempted real tasks
RAMFS-MOUNTED                 a FAT12 volume was formatted and mounted
MODULE-LOADED-FROM-FILE       a module was read from that volume and run
PICFMT2_SELFTEST: ALL PASSED  the module loader passed its self-test
SHELL-FS: ALL PASSED          the shell's filesystem commands work
TUWA-KERNEL-RUNNING           the kernel reached steady state

The first line is the load-bearing one. Two tasks spin without ever yielding and without ever blocking, so neither can make progress unless the timer tick takes the CPU away from the other. If both counters moved, preemption is working on that hardware. A test that only proved tasks start would pass on a system that never switches.

What a default image contains

The reference BSPs link the kernel, the CPU port, the board drivers, a FAT12 filesystem on a RAM disk, the module loader and the shell.

Not linked: the network drivers and the IP stack's upper layers. A first bring-up should tell you whether the kernel schedules, not which of several subsystems broke - and networking needs hardware the emulated boards do not model.

Subsystems are added by naming their source files and one build flag; nothing is conditional inside the kernel. 02-build-guide.md gives the exact lines.

If you leave the filesystem out, TuwaLoadModuleFromFile() returns MODERR_NO_FILESYSTEM - a specific error naming the real cause rather than "file not found" sending you to look for a file. Modules can still be loaded from memory with TuwaLoadModule().