Skip to main content

Crate osal_rs

Crate osal_rs 

Source
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 definitions
  • log - Logging macros
  • traits - Private module defining the trait abstractions
  • freertos - Private FreeRTOS implementation (enabled with freertos feature)
  • posix - Private POSIX implementation (enabled with posix feature, planned)

§Features

  • freertos - Enable FreeRTOS support (default)
  • posix - Enable POSIX support (planned)
  • std - Enable standard library support for testing
  • disable_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.h options:
    • configTICK_RATE_HZ - Defines the tick frequency
    • configUSE_MUTEXES - Must be 1 for mutex support
    • configUSE_COUNTING_SEMAPHORES - Must be 1 for semaphore support
    • configUSE_TIMERS - Must be 1 for timer support
    • configSUPPORT_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_isr suffix 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_isr variants)
  • 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

  1. Thread Creation: Always specify appropriate stack sizes based on usage
  2. Mutexes: Prefer scoped locking with guards to prevent deadlocks
  3. Queues: Use type-safe QueueStreamed when possible
  4. Semaphores: Use binary semaphores for signaling, counting for resources
  5. ISR Handlers: Keep ISR code minimal, defer work to tasks
  6. Error Handling: Always check Result return 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.
print
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.