Linmo
Features
-
Minimal kernel footprint optimized for resource-constrained environments.
-
Lightweight task model where all tasks operate within a single shared address space.
-
Support for both preemptive and cooperative multitasking modes based on application return values.
-
Priority-based round-robin scheduling algorithm with eight distinct priority levels.
-
Support for a user-defined real-time scheduler to override default policies for specific tasks.
-
Task synchronization via counting semaphores and mutexes with condition variables.
-
Inter-task communication using unidirectional, byte-oriented pipes.
-
Message queue and event queue support for structured data exchange.
-
Software timers with user-defined callback functionality for periodic events.
-
Dynamic memory management providing standard malloc, calloc, realloc, and free operations.
-
Dedicated stack allocation per task from a shared system heap.
-
Hardware Abstraction Layer (HAL) to decouple kernel logic from architecture-specific code.
-
Compact, built-in C library (LibC) to minimize binary size and external dependencies.
-
Configurable task priorities ranging from Idle to Critical levels.
-
Native support for the RISC-V RV32I architecture.
Linmo follows a monolithic-style kernel design where all tasks share a single address space, significantly reducing the overhead associated with memory management units (MMU) and context switching in resource-constrained environments. The kernel is structured around a Hardware Abstraction Layer (HAL) that isolates architecture-specific code—currently targeting RISC-V RV32I—from the core kernel logic, facilitating portability and testing via QEMU.
The core execution unit is the “Task,” which is allocated a dedicated stack from the system heap during initialization. Scheduling is handled by a priority-based round-robin engine that supports both cooperative (yield-based) and preemptive (interrupt-driven) execution. A unique feature is the ability to hook a user-defined real-time scheduler to handle high-priority tasks, bypassing the default policy when specialized timing requirements are necessary.
Core Components
- Scheduler: Priority-based round-robin with support for custom real-time policies.
- Memory Manager: Dynamic heap allocator providing standard memory management functions.
- IPC Subsystem: Implements semaphores, mutexes, condition variables, pipes, and message queues.
- HAL (Hardware Abstraction Layer): Manages CPU context, interrupts, and timer hardware for RISC-V.
- Compact LibC: A minimal implementation of standard C functions optimized for code size.
Use Cases
This RTOS is ideal for:
- Educational Platforms: Specifically designed as a teaching tool for understanding RTOS internals, context switching, and scheduling on RISC-V.
- Resource-Constrained IoT: Suitable for simple microcontrollers where memory footprint is critical and full process isolation is not required.
- Prototyping RISC-V Applications: Provides a quick-start environment for testing RV32I code in a multi-tasking environment using QEMU.
Getting Started
To begin developing with Linmo, you need a RISC-V cross-compilation toolchain (riscv-none-elf) and QEMU (qemu-system-riscv32). The build process is managed via Makefiles; running make generates the core kernel library liblinmo.a. Developers can create applications in the app/ directory and link them against the kernel. The kernel’s behavior (preemptive vs. cooperative) is determined by the return value of app_main(). Detailed contribution guidelines and source code structure are available in the repository’s CONTRIBUTING.md and README.md files.