Expand description
§OSAL-RS - Operating System Abstraction Layer for Rust
A cross-platform abstraction layer for embedded and real-time operating systems.
§Overview
OSAL-RS provides a unified, safe Rust API for working with different real-time operating systems. Currently supports FreeRTOS with planned support for POSIX and other RTOSes.
§Features
- Thread Management: Create and control threads with priorities
- Synchronization: Mutexes, semaphores, and event groups
- Communication: Queues for inter-thread message passing
- Timers: Software timers for periodic and one-shot operations
- Time Management: Duration-based timing with tick conversion
- No-std Support: Works in bare-metal embedded environments
- Type Safety: Leverages Rust’s type system for correctness
§Quick Start
§Basic Thread Example
ⓘ
use osal_rs::os::*;
use core::time::Duration;
fn main() {
// Create a thread
let thread = Thread::new(
"worker",
4096, // stack size
5, // priority
|| {
loop {
println!("Working...");
Duration::from_secs(1).sleep();
}
}
).unwrap();
thread.start().unwrap();
// Start the scheduler
System::start();
}§Mutex Example
ⓘ
use osal_rs::os::*;
use alloc::sync::Arc;
let counter = Arc::new(Mutex::new(0));
let counter_clone = counter.clone();
let thread = Thread::new("incrementer", 2048, 5, move || {
let mut guard = counter_clone.lock().unwrap();
*guard += 1;
}).unwrap();§Queue Example
ⓘ
use osal_rs::os::*;
use core::time::Duration;
let queue = Queue::new(10, 4).unwrap();
// Send data
let data = [1u8, 2, 3, 4];
queue.post(&data, 100).unwrap();
// Receive data
let mut buffer = [0u8; 4];
queue.fetch(&mut buffer, 100).unwrap();§Semaphore Example
ⓘ
use osal_rs::os::*;
use core::time::Duration;
let sem = Semaphore::new(1, 1).unwrap();
if sem.wait(Duration::from_millis(100)).into() {
// Critical section
sem.signal();
}§Timer Example
ⓘ
use osal_rs::os::*;
use core::time::Duration;
let timer = Timer::new_with_to_tick(
"periodic",
Duration::from_millis(500),
true, // auto-reload
None,
|_, _| {
println!("Timer tick");
Ok(None)
}
).unwrap();
timer.start_with_to_tick(Duration::from_millis(10));§Module Organization
os- Main module containing all OS abstractions- Threads, mutexes, semaphores, queues, event groups, timers
- System-level functions
- Type definitions
utils- Utility types and error definitionslog- Logging macrostraits- Private module defining the trait abstractionsfreertos- Private FreeRTOS implementation (enabled withfreertosfeature)posix- Private POSIX implementation (enabled withposixfeature, planned)
§Features
freertos- Enable FreeRTOS support (default)posix- Enable POSIX support (planned)std- Enable standard library support for testingdisable_panic- Disable the default panic handler and allocator
§Requirements
When using with FreeRTOS:
- FreeRTOS kernel must be properly configured
- Link the C porting layer from
osal-rs-porting/freertos/ - Set appropriate
FreeRTOSConfig.hoptions:configTICK_RATE_HZ- Defines the tick frequencyconfigUSE_MUTEXES- Must be 1 for mutex supportconfigUSE_COUNTING_SEMAPHORES- Must be 1 for semaphore supportconfigUSE_TIMERS- Must be 1 for timer supportconfigSUPPORT_DYNAMIC_ALLOCATION- Must be 1 for dynamic allocation
§Platform Support
Currently tested on:
- ARM Cortex-M (Raspberry Pi Pico/RP2040, RP2350)
- ARM Cortex-M4F (STM32F4 series)
- ARM Cortex-M7 (STM32H7 series)
- RISC-V (RP2350 RISC-V cores)
§Thread Safety
All types are designed with thread safety in mind:
- Most operations are thread-safe and can be called from multiple threads
- Methods with
_from_isrsuffix are ISR-safe (callable from interrupt context) - Regular methods (without
_from_isr) must not be called from ISR context - Mutexes use priority inheritance to prevent priority inversion
§ISR Context
Operations in ISR context have restrictions:
- Cannot block or use timeouts (must use zero timeout or
_from_isrvariants) - Must be extremely fast to avoid blocking other interrupts
- Use semaphores or queues to defer work to task context
- Event groups and notifications are ISR-safe for signaling
§Safety
This library uses unsafe internally to interface with C APIs but provides
safe Rust abstractions. All public APIs are designed to be memory-safe when
used correctly:
- Type safety through generic parameters
- RAII patterns for automatic resource management
- Rust’s ownership system prevents data races
- FFI boundaries are carefully validated
§Performance Considerations
- Allocations happen on the FreeRTOS heap, not the system heap
- Stack sizes must be carefully tuned for each thread
- Priority inversion is mitigated through priority inheritance
- Context switches are triggered by blocking operations
§Best Practices
- Thread Creation: Always specify appropriate stack sizes based on usage
- Mutexes: Prefer scoped locking with guards to prevent deadlocks
- Queues: Use type-safe
QueueStreamedwhen possible - Semaphores: Use binary semaphores for signaling, counting for resources
- ISR Handlers: Keep ISR code minimal, defer work to tasks
- Error Handling: Always check
Resultreturn values
§License
LGPL-2.1-or-later - See LICENSE file for details
Modules§
- log
- Logging system for embedded environments.
- os
- Main OSAL module re-exporting all OS abstractions and traits.
- utils
- Utility types and functions for OSAL-RS.
Macros§
- access_
static_ option - Accesses a static Option variable, returning the contained value or panicking if None.
- cpu_
clock_ hz - Returns the CPU clock frequency in Hz.
- from_
c_ str - Converts a C string pointer to a Rust String.
- from_
str_ to_ array - Converts a string to a fixed-size byte array.
- log_
debug - Logs a DEBUG level message.
- log_
error - Logs an ERROR level message.
- log_
fatal - Logs a FATAL level message.
- log_
info - Logs an INFO level message.
- log_
warning - Logs a WARNING level message.
- max_
priorities - Returns the maximum number of priority levels.
- max_
task_ name_ len - Returns the maximum length for task names.
- minimal_
stack_ size - Returns the minimum stack size for tasks.
- Prints formatted text to UART without a newline.
- println
- Prints formatted text to UART with a newline (\r\n).
- thread_
extract_ param - Extracts a typed parameter from an optional boxed Any reference.
- tick_
period_ ms - Returns the tick period in milliseconds.
- tick_
rate_ hz - Returns the RTOS tick rate in Hz.
- to_
c_ str - Converts a Rust string to a C string pointer.
- to_
cstring - Converts a Rust string to a CString with error handling.