Skip to main content

Crate ove

Crate ove 

Source
Expand description

oveRTOS Rust SDK — safe wrappers for the oveRTOS embedded RTOS framework.

Provides RAII types for threads, mutexes, semaphores, queues, timers, etc. and the app! macro that generates all FFI boilerplate so application code can be written in pure safe Rust.

§Async (Embassy)

Activated by the async Cargo feature combined with C-side CONFIG_OVE_ASYNC=y. Adds an Embassy-based async runtime hosted on the oveRTOS substrate:

use embassy_executor::Spawner;
use embassy_time::{Duration, Timer};

#[embassy_executor::task]
async fn blinker() {
    loop {
        log::info!("tick");
        Timer::after(Duration::from_millis(250)).await;
    }
}

#[ove::main]
async fn app_main(spawner: Spawner) {
    spawner.must_spawn(blinker());
}

Under the hood:

  • async_runtime::Executor wraps embassy_executor::raw::Executor and blocks on ove_event_wait between polls — yields cleanly to the FreeRTOS / Zephyr / NuttX scheduler. No WFE busy-park, no host-thread parking.
  • async_runtime::AsyncStream / AsyncQueue / AsyncEventGroup / AsyncSemaphore / AsyncUart / AsyncInput wrap the corresponding synchronous primitives and bridge their C-level _set_notify hooks into embassy_sync::waitqueue::AtomicWaker.
  • Time driver: embassy_time::Timer::after_*() runs on a re-armable ove_timer_*_ns one-shot.
  • Critical-section impl: ove_irq_lock / ove_irq_unlock on every target.

Cargo feature: enable async. The optional embedded-io-async feature adds embedded_io_async::Read impls on &'static AsyncUart and &'static AsyncStream.

§Async networking (embassy-net)

Layered on top of the async runtime, async_net adds an embassy_net::Stack backed by a per-board Ethernet Driver (QemuShmDriver for QEMU MPS2-AN500, Stm32f7EthDriver for the STM32F746G-Discovery). Open async TCP / UDP / DNS sockets via the standard embassy_net types; pair with crates.io community libraries (reqwless, rust-mqtt, embedded-tls, picoserve) for the protocol layers.

Mutually exclusive with the blocking net stack at build time — both want to own the MAC. Cargo features: async-net plus a transport sub-feature (async-net-qemu-shm, async-net-stm32f7-eth) and C-side CONFIG_OVE_ASYNC_NET=y. See the async_net module docs for the full decision guide vs. blocking net, the community-crate pairing recipes, and hardware-verified memory budgets on STM32F7.

§Ergonomic extras

A handful of small additions modelled on patterns from zephyr-lang-rust and embassy-sync that come up often enough to warrant first-class support:

  • channel — crossbeam-style MPMC Sender / Receiver over the existing Queue FFI. Cloneable halves, refcounted, with half-closed detection (Error::NetClosed). Heap mode uses an internal Arc; zero-heap uses channel::Sender::from_static / channel::Receiver::from_static against caller-supplied counters.
  • config — every CONFIG_OVE_* symbol from ove_config.h surfaces as a Rust const (bool / i64 / &str, plus _USIZE for non-negative ints) and a #[cfg(config_ove_*)] flag. Lets apps reference build-time tunables (e.g. CONFIG_OVE_PM_MAX_WAKE_SOURCES_USIZE) without hard-coding the number twice.
  • printk! / printkln! / ove_print! — direct ove_console_write macros that bypass the log framework. Use for early-boot banners before log::try_init runs and for ISR-adjacent contexts.
  • sync::SpinMutex — IRQ-locking mutex (ove_irq_lock-backed) for sub-microsecond critical sections, ISR-shared state, and crossing .await points where a real sync::Mutex would deadlock. Requires the async feature (the ove_irq_* substrate lives in irq.h under CONFIG_OVE_ASYNC); not available on WASM.
  • ove_macros::thread (#[ove::thread(stack_size = N, name = "...")]) — attribute-macro form of static-storage thread spawn. The decorated fn name() becomes a spawn helper that, on first call, creates a thread with a static ThreadStorage<N>. Complements the existing declarative thread! macro.

§Optional ecosystem interop

Two opt-in Cargo features add ecosystem-standard types alongside the defaults (neither is enabled by default — the existing API stays unchanged for callers who don’t opt in):

§Hot-path inline discipline

Wrapper methods that are a thin unsafe { ffi::ove_*(...) } plus Error::from_code(rc) are marked #[inline] so the rustc/LLVM optimizer can fold the FFI call, the error-code match, and the Result construction into the caller’s frame. Without this, Mutex::lock and friends compile as out-of-line bl targets that cost an extra ~20–60 ns per call on Cortex-M and show up as a 6–15% per-binding overhead on the shortest sync paths. The same discipline applies to any new wrapper added here — keep the body a one-liner and add #[inline].

Cross-language inlining between Rust and C is gated behind the OVE_CROSS_LTO=ON CMake option. It is off by default because it requires a bitcode-aware linker and a target-cpu/target-feature match that the embedded toolchains do not always provide; per Gale’s “three quiet barriers” analysis, mismatched feature sets silently kill the inliner without warning.

Re-exports§

pub use async_runtime::AsyncEventGroup;
pub use async_runtime::AsyncI2c;
pub use async_runtime::AsyncInput;
pub use async_runtime::AsyncQueue;
pub use async_runtime::AsyncSemaphore;
pub use async_runtime::AsyncSpi;
pub use async_runtime::AsyncStream;
pub use async_runtime::AsyncUart;
pub use async_runtime::Executor;
pub use cell::LvCell;
pub use cell::LvRefCell;
pub use error::Error;
pub use error::Result;
pub use eventgroup::EG_CLEAR_ON_EXIT;Deprecated
pub use eventgroup::EG_WAIT_ALL;Deprecated
pub use eventgroup::EventGroup;
pub use eventgroup::EventGroupStorage;
pub use eventgroup::WaitFlags;
pub use fmt::FmtBuf;
pub use i2c::I2c;
pub use init_cell::InitCell;
pub use init_cell::InitMut;
pub use queue::Queue;
pub use queue::QueueStorage;
pub use spi::Spi;
pub use stream::Stream;
pub use stream::StreamStorage;
pub use sync::CondVar;
pub use sync::CondVarStorage;
pub use sync::Event;
pub use sync::EventStorage;
pub use sync::Mutex;
pub use sync::MutexGuard;
pub use sync::MutexStorage;
pub use sync::RecursiveMutex;
pub use sync::RecursiveMutexGuard;
pub use sync::RecursiveMutexStorage;
pub use sync::Semaphore;
pub use sync::SemaphoreStorage;
pub use sync::WaitTimeoutResult;
pub use thread::Priority;
pub use thread::Builder;
pub use thread::JoinHandle;
pub use thread::JoinHandleBorrowed;
pub use thread::MemStats;
pub use thread::StopToken;
pub use thread::Thread;
pub use thread::ThreadInfo;
pub use thread::ThreadState;
pub use thread::ThreadStats;
pub use time::Delay;
pub use timer::Timer;
pub use timer::TimerStorage;
pub use uart::Uart;
pub use watchdog::Watchdog;
pub use workqueue::Work;
pub use workqueue::Workqueue;

Modules§

async_net
Async networking via embassy-net.
async_runtime
Embassy-based async runtime hosted on the oveRTOS C substrate.
audio
Audio graph engine for oveRTOS.
board
Board initialization and identification for oveRTOS.
bsp
Backward-compatible BSP module — delegates to board, gpio, led modules.
cell
Single-threaded interior-mutability primitives.
channel
Crossbeam-style MPMC channel over crate::Queue.
config
Build-time configuration exposed as Rust consts and cfg flags.
console
Low-level console I/O for oveRTOS.
containers
Fixed-capacity containers re-exported from heapless.
error
oveRTOS error types and the Result alias.
eventgroup
Event group (bitfield synchronization) for oveRTOS.
fmt
Stack-allocated formatting buffer for no_std environments.
fs
Filesystem abstraction for oveRTOS.
gpio
GPIO control for oveRTOS.
heap
Heap-allocating types re-exported from alloc::*. Available with the alloc (or std) feature. On no_std targets the consumer must register a #[global_allocator]; the ove-allocator crate provides a default that wraps libc malloc/free.
i2c
I2C bus master driver.
i2s
I²S audio bus driver.
infer
ML inference primitives for oveRTOS.
init_cell
Init-once container for static declarations.
led
LED control for oveRTOS boards.
log
log::Log backend for oveRTOS.
lvgl
Safe LVGL v9 wrappers for the oveRTOS Rust SDK.
net
Blocking BSD-style networking primitives for oveRTOS.
net_http
Blocking HTTP/1.1 client with RAII response management.
net_httpd
Blocking embedded HTTP server with REST-style routing.
net_mqtt
Blocking MQTT 3.1.1 client with safe callback.
net_sntp
Blocking SNTP time synchronization client.
net_tls
Blocking TLS/SSL session wrapper (mbedTLS).
nvs
Non-Volatile Storage (NVS) subsystem for oveRTOS.
pm
Power management framework for oveRTOS.
queue
Type-safe FIFO queue for oveRTOS.
shell
Interactive shell subsystem for oveRTOS.
spi
SPI bus master driver.
stream
Byte-stream buffer for oveRTOS.
sync
Synchronization primitives for oveRTOS.
thread
RTOS thread management.
time
Time and delay utilities for oveRTOS.
timer
Software timer for oveRTOS.
uart
UART serial bus driver.
watchdog
Hardware watchdog timer for oveRTOS.
workqueue
Work queue and deferred work items for oveRTOS.

Macros§

audio_graph
Create a crate::audio::Graph that works in both heap and zero-heap modes.
condvar
Create a crate::CondVar that works in both heap and zero-heap modes.
event
Create an crate::Event that works in both heap and zero-heap modes.
event_handler
Declare a static crate::lvgl::EventHandler<T> for LVGL event callbacks.
eventgroup
Create an crate::EventGroup that works in both heap and zero-heap modes.
http_client
Create a crate::net_http::Client that works in both heap and zero-heap modes. In zero-heap mode the response body and headers borrow into the client’s embedded _resp_buf[CONFIG_OVE_NET_HTTP_MAX_RESPONSE] and are valid until the next request.
model_data
Declare a safe accessor for TFLite model data generated by convert.py.
mqtt_client
Create a crate::net_mqtt::Client that works in both heap and zero-heap modes. In zero-heap mode the per-connection RX/TX buffers (CONFIG_OVE_NET_MQTT_RX_BUF / CONFIG_OVE_NET_MQTT_TX_BUF) live in the client storage.
mutex
Create a crate::Mutex<T> around $val that works in both heap and zero-heap modes.
ove_print
Alias for printk! using the ove_print! name.
printk
Format + write to the console without going through the log framework. Useful for early-boot debug (before log::init()) and for ISR-adjacent contexts.
printkln
printk! variant that appends a newline.
queue
Create a crate::Queue that works in both heap and zero-heap modes.
recursive_mutex
Create a crate::RecursiveMutex that works in both heap and zero-heap modes.
semaphore
Create a crate::Semaphore that works in both heap and zero-heap modes.
shared
Declare a static wrapped in crate::InitCell for cross-thread shared state.
shared_mut
Declare a static wrapped in crate::InitMut for single-owner mutable state.
stream
Create a crate::Stream that works in both heap and zero-heap modes.
thread
Create a crate::JoinHandle for a thread that works in both heap and zero-heap modes.
timer
Create a crate::Timer that works in both heap and zero-heap modes.
tls_session
Create a crate::net_tls::Session that works in both heap and zero-heap modes. In zero-heap mode the session draws its mbedTLS state from a file-scope static and the per-protocol static buffer (CONFIG_OVE_NET_TLS_HEAP_SIZE).
watchdog
Create a crate::Watchdog that works in both heap and zero-heap modes.
work
Create a crate::Work item that works in both heap and zero-heap modes.
work_handler
Wrap a safe Rust fn() into an ove_work_fn C trampoline.
workqueue
Create a crate::Workqueue that works in both heap and zero-heap modes.

Functions§

log
Write a message to the oveRTOS console.
run
Start audio (if enabled) and the RTOS scheduler. Blocks forever.
start_scheduler
Start the RTOS scheduler without engaging the zero-heap lock.

Attribute Macros§

main
#[ove::main] proc-macro: marks the application entry point. Expands into the extern "C" fn ove_main() trampoline. Attribute macro: mark a function as the oveRTOS application entry point.
thread_attr
#[ove::main] proc-macro: marks the application entry point. Expands into the extern "C" fn ove_main() trampoline. Attribute macro: declare a function as a thread entry-point with a statically-allocated stack. Calling the generated wrapper spawns the thread once; subsequent calls return Err(Error::Inval) (the underlying [ove::ThreadStorage] is single-use).