Skip to content
View AhuraRTOS's full-sized avatar
💭
We Are Thinking
💭
We Are Thinking

Block or report AhuraRTOS

Block user

Prevent this user from interacting with your repositories and sending you notifications. Learn more about blocking users.

You must be logged in to block users.

Content in all repositories owned by your account will be closed.
Maximum 250 characters. Please don’t include any personal information such as legal names or email addresses. Markdown is supported. This note will only be visible to you.
Report abuse

Contact GitHub support about this user’s behavior. Learn more about reporting abuse.

Report abuse
AhuraRTOS/README.md

⚡ AhuraRTOS

A small, portable, preemptive RTOS for microcontrollers.

One public header · no editable kernel files · every feature a compile-time switch

License: GPL v3 Standard: C11 Architectures: Cortex-M | RISC-V Toolchains: GCC | Clang | armclang Status: under development

Why · Features · Verified · Install · Documentation

Warning

Early and under active development. The kernel is functional and self-testing on every board in the table below, but APIs may still change and it is not yet recommended for production use.

Why AhuraRTOS

It costs one exception vector. The kernel takes over the lowest-priority exception - PendSV on Cortex-M, the machine software interrupt on RISC-V - and nothing else. SVC is left entirely to the application, which keeps it compatible with everything that legitimately wants it: Nordic's SoftDevice, TF-M and other secure firmware, vendor bootloaders and ROM APIs. The tick is a single application call to os_tick_handler(), and its timer is configurable, so parts whose SysTick stops in low-power modes are first-class rather than special cases. No HAL, no CMSIS dependency, no linker-script edits.

Misintegration fails loudly. The kernel checks at boot that the vector table really routes the switch to it, and traps at the cause if not. The usual alternative is a board that reaches os_start() and stops dead - no fault, no output, nothing to attach a debugger to. The same principle runs through the API: missing callbacks are link errors naming the function, an incomplete os_config.h is a compile error, and a port/-mcpu mismatch fails to compile rather than producing a subtly wrong context switch.

You never edit a kernel file. One template becomes your os_config.h, and that is the single source of configuration for both the kernel library and your application. Updating the kernel is a drop-in replacement of AhuraRTOS/, every time - there are no local modifications to re-apply, because there are none to make.

Every feature is a compile-time switch. OS_CONFIG_<FEATURE>_ENABLE removes code, RAM and API surface - not just runtime behavior. And nothing in the kernel allocates dynamically: task blocks, ready lists, timer objects, the log ring and the optional heap are all static, so what a build costs is decided at compile time and visible in the map file.

The scheduler is O(1), and so is deciding not to run it. One FIFO ready list per priority plus a 32-bit ready bitmap: the next task is a CLZ and a list head, whatever the task count. A tick that would not switch anything costs one bitmap check instead of a full context-switch round trip.

Barriers that fit what you are actually guarding. A scheduler lock that defers preemption without masking a single interrupt - the barrier a critical section cannot be. Critical sections that can mask with BASEPRI instead of PRIMASK, leaving urgent ISRs with zero kernel-induced latency. And a full atomic set that is lock-free wherever the instruction set allows it.

Priority inheritance is always on. No switch to turn it off while still calling the object a mutex, and the accounting stays correct when one task holds several contended mutexes at once. What inheritance cannot do is prevent a deadlock - that is a lock-ordering fault, not a timing one - so development builds detect that instead: blocking on a mutex whose wait chain leads back to you asserts the moment the cycle would form, while the guilty call stack is still there to read, rather than leaving a board that silently stops.

It proves itself on your board. A built-in self-test suite exercises every enabled feature over printf, with no application code and no board support, and finishes with a cycle-accurate benchmark table for every hot kernel path. Bring-up is: flash it, read the console, then start writing firmware.

Two instruction sets, one kernel. M0 through M85 - ARMv6-M to ARMv8.1-M - across three shared port implementations, plus RV32 on Hazard3. Nothing in the kernel names a vendor, a family, or a HAL, and adding an architecture is a new port rather than a kernel change.

What you get

Scheduling Preemptive, 31 priority levels, one FIFO ready list per priority, O(1) pick, configurable round-robin
Sync & IPC Mutexes with priority inheritance · counting semaphores · queues, static or heap-backed · variable-length message buffers · event groups · per-task notifications - all with millisecond timeouts
Timers One-shot and periodic software timers, plus caller-owned deferred-call pools, all delivered on one service task so callbacks run in task context
Memory An optional first-fit kernel heap with coalescing. Everything else is static
Diagnostics Stack watermarking · stack-overflow detection · mutex deadlock detection · CPU-load sampling · buffered logging that never stalls the caller
Multi-core SMP scheduling with a per-task core-affinity mask over shared ready lists
Security TrustZone on ARMv8-M: secure, non-secure or disabled, per build

A complete application, in full:

int main(void)
{
    SystemClock_Config();

    os_init();      /* idle task, service tasks, your default task, the tick */
    os_start();     /* never returns */
}

void os_main(void)  /* your application - already a running task */
{
    while (1)
    {
        my_led_toggle();
        os_delay_ms(500U);
    }
}

os_init() creates and starts a default task for you, so there is nothing to declare just to get moving. Every feature above is described with the mechanism behind it in the kernel reference.

Verified on hardware

The self-test suite is not a CI badge - it runs on the board. Every row below is a real part that has run the full suite to completion:

Board Cores Self-test Dual-core SMP
Raspberry Pi Pico 2 2 × Cortex-M33 (RP2350)
Raspberry Pi Pico 2 2 × Hazard3 RV32 (RP2350)
Raspberry Pi Pico 2 × Cortex-M0+ (RP2040)
NUCLEO-H743ZI Cortex-M7 (STM32H7) single-core part
NUCLEO-H503RB Cortex-M33 (STM32H5) single-core part
NUCLEO-G431RB Cortex-M4 (STM32G4) single-core part

That covers every port the kernel has - ARMv6-M, ARMv7-M, ARMv8-M and RV32 - and both dual-core models, Arm and RISC-V.

Tickless idle runs on all six, driven by the idle task, and the suite measures it rather than assuming it: it counts tick-interrupt entries across a window of known length and reads 0 or 1 against 40. Deep sleep with an LPTIM is proven on the G431 and H503; the other boards use a SoC wake source or SysTick's own reload.

Not yet run on silicon: TrustZone - it builds and its callbacks are wired, but no part with the Security Extension has run it. It is on the roadmap rather than claimed here.

Install it

On a Raspberry Pi Pico SDK or STM32CubeMX project it is one command, which prints the exact diff it wants to apply and waits for a y before touching anything. On STM32 that diff now includes the .ioc: the installer clears the two CubeMX boxes that would generate vectors the kernel owns, so a later Generate Code agrees with it. One setting stays yours - the HAL time base. Every installer has an offline twin for machines with no internet, and the same integration by hand is six steps on any other vendor, IDE or build system.

Installing AhuraRTOS is the table that names all three routes for every packaged chip.

Documentation

📖 Documentation index - or go straight to a page:

Page What is in it
Start here
Installing AhuraRTOS The pick-your-chip table - all three routes per chip - then the general procedure: six steps, any vendor, IDE and build system
AhuraRTOS on STM32 Everything STM32 in one page. Three install routes - automatic, offline, manual with the exact CubeMX checkboxes - then the st/stm32 package
AhuraRTOS on Raspberry Pi Everything RP2040 / RP2350 / RP2354 in one page. Three install routes - automatic, offline, manual - then the three packages, Arm and RISC-V
Vendor notes The one thing that differs per vendor - whether its code generator emits a competing PendSV_Handler - on STM32, Nordic, NXP, TI, Silicon Labs, Renesas, Microchip, Infineon, GD32 and anything else
Running the self-test suite Prove a fresh port before writing anything on top of it: how to enable it, how to read the output, why a silent console is usually the libc, and how much flash to budget
The kernel
Kernel reference The authoritative reference. What the kernel is, and the entry point to the five pages below
Using the kernel Every API: tasks, priorities, mutexes, queues, message buffers, notifications, atomics, timers, deferred calls, the heap, diagnostics and debugging
How the kernel works Boot, the scheduler, the context switch, the tick, blocking and waking, priority inheritance, and where the RAM goes
What the kernel needs from a platform The reference behind the install: non-CMake build inputs, every os_config.h option, and the two-item integration contract
Platform support The callbacks a platform must supply, the clock, TrustZone, multi-core and tickless idle
Tickless idle The whole suppressed-tick contract on one page: who masks, who plans, who clamps, who measures, who may sleep, what each port and each SoC package does, and how to prove it on a board
Source layout What each directory and each kernel/ source file is, and why os_internal.h is reachable from none of them
SoC packages The optional per-silicon layer under soc/: who owns which callback, what may and may not live there, and how to write one. The four packaged parts are documented in the two vendor pages above
Testing and examples
Testing and examples The self-test suite and the runnable examples, together
Examples One runnable os_main.c per kernel feature, and how to run them
The project
Platforms Which cores, vendors and toolchains are supported today, what is planned, and what is experimental
Roadmap The three phases, the known gaps tracked for later, and the current status
C style The style every file in this repository is written to

Repository layout

AhuraRTOS/
├── CMakeLists.txt  <- builds the ahura_kernel library; the application calls
│                      add_subdirectory(AhuraRTOS) and links ahura_kernel
├── ahura.h         <- the public umbrella header; applications include only this
├── kernel/         <- the portable core: scheduler, sync and IPC, timers, memory,
│                      log. Plain C11, no CPU knowledge anywhere in it
├── arch/           <- the port layer, <family>/<core>: arm/ and riscv/ today.
│                      Everything a CPU changes is confined here
├── soc/            <- optional per-silicon packages, <vendor>/<family> (see doc/soc.md)
├── template/       <- the files you copy into your project: os_config.h, os_cb.c,
│                      os_main.c, plus soc_cb.c when no SoC package covers the part
├── test/           <- the self-test suite, built as its own os_test library
├── examples/       <- one runnable main per feature
├── doc/            <- every documentation page, including the per-SoC ones
├── tools/          <- the four install_*.py, and nothing else you need to open.
│                      Each is a small bootstrap: it locates an AhuraRTOS checkout -
│                      downloading one if it has to - then loads the engine and the
│                      vendor descriptor out of tools/internal/. Adding a platform
│                      is one file there; the engine and the bootstraps do not change
├── CSTYLE.md       <- the C style every file here is written to
├── LICENSE
└── README.md       <- this file

The three axes the layout separates are the three questions a port asks: kernel/ never changes, arch/ changes with the instruction set, soc/ changes with the chip.

One repository, no submodules - a plain clone gives you everything:

git clone https://github.com/AhuraRTOS/AhuraRTOS.git

Contributing

Contributions are welcome. Kernel work, new ports, testing, and documentation all help. Open an issue or submit a pull request.

License

GNU General Public License v3.0 or later. See LICENSE.

Pinned Loading

  1. AhuraRTOS AhuraRTOS Public

    The Versatile RTOS for All MCU

    C 45 3