zephyr/
lib.rs

1// Copyright (c) 2024 Linaro LTD
2// SPDX-License-Identifier: Apache-2.0
3
4//! Zephyr application support for Rust
5//!
6//! This crates provides the core functionality for applications written in Rust that run on top of
7//! Zephyr.  The goal is to bridge the two worlds.  The functionality provided here shouldn't be too
8//! distant from how Zephyr does things.  But, it should be "rusty" enough that Rust developers feel
9//! comfortable using it.
10//!
11//! Some functionality:
12//!
13//! - [`time`]: The time module provides a [`Instant`] and [`Duration`] type that are similar to those
14//!   in `std`, but are tailored for embedded systems.  These are bridged through traits, so that most
15//!   API calls that offer a timeout will accept either an `Instant` or a `Duration`.
16//! - [`sync`]: This crate provides various synchronization primitives that can be used to coordinate
17//!   between threads.  These include
18//!   - [`sync::atomic`]: Provides the same functionality as [`std::sync::atomic`], but on targets
19//!     with limited synchronization primtives, re-exports features from the 'portable-atomic'
20//!     crate, which can emulate atomics using critical sections.
21//!   - [`sync::channel`]: Channel based synchronization built around the `k_queue` channels
22//!     provided by Zephyr.  This provides both `alloc`-based unbounded channels, and bounded
23//!     channels that pre-allocate.
24//!   - [`sync::Mutex`]/[`sync::Condvar`]: `std`-style Mutexes and condition variables, where the
25//!     Mutex protects some piece of data using Rust's features.
26//!   - [`sync::SpinMutex`]: A Mutex that protects a piece of data, but does so using a spinlock.
27//!     This is useful where data needs to be used exclusively, but without other types of
28//!     synchronization.
29//!   - [`sync::Arc`]: Atomic reference counted pointers.  Mostly like [`std::sync::Arc`] but supports
30//!     all targets that support Rust on Zephyr.
31//! - [`sys`]: More direct interfaces to Zephyr's primitives.  Most of the operations in `sync` are
32//!   built on these.  These interfaces are 'safe', as in they can be used without the `unsafe`
33//!   keyword, but the interfaces in `sync` are much more useful from Rust programs.  Although most
34//!   things here won\t typically be needed, two standout:
35//!   - [`sys::thread`]: A fairly direct, but safe, interface to create Zephyr threads.  At this
36//!     point, this is the primary way to create threads in Rust code (see also [`work`] which
37//!     supports multiple contexts using Zephyr's work queues.
38//!   - [`sys::sync::Semaphore`]: The primitive Semaphore type from Zephyr.  This is the one lower
39//!     level operation that is still quite useful in regular code.
40//! - [`timer`]: Rust interfaces to Zephyr timers.  These timers can be used either by registering a
41//!   callback, or polled or waited for for an elapsed time.
42//! - [`work`]: Zephyr work queues for Rust.  The [`work::WorkQueueBuilder`] and resulting
43//!   [`work::WorkQueue`] allow creation of Zephyr work queues to be used from Rust.  The
44//!   [`work::Work`] item had an action that will be invoked by the work queue, and can be manually
45//!   submitted when needed.
46//! - [`logging`]: A logging backend for Rust on Zephyr.  This will log to either `printk` or
47//!   through Zephyr's logging framework.
48//!
49//! [`Instant`]: time::Instant
50//! [`Duration`]: time::Duration
51//! [`std::sync::atomic`]: https://doc.rust-lang.org/std/sync/atomic/
52//! [`std::sync::Arc`]: https://doc.rust-lang.org/std/sync/struct.Arc.html
53//!
54//! In addition to the above, the [`kconfig`] and [`devicetree`] provide a reflection of the kconfig
55//! settings and device tree that were used for a specific build.  As such, the documentation
56//! provided online is not likely to be that useful, and for these, it is best to generate the
57//! documentation for a specific build:
58//! ```bash
59//! $ west rustdoc
60//! ```
61//!
62//! Note, however, that the `kconfig` module only provides Kconfig **values**, and doesn't provide a
63//! mechanmism to base conditional compilation.  For that, please see the
64//! [zephyr-build](../../std/zephyr_build/index.html) crate, which provides routines that can be
65//! called from a `build.rs` file to make these settings available.
66
67#![no_std]
68#![allow(unexpected_cfgs)]
69#![deny(missing_docs)]
70
71pub mod align;
72pub mod device;
73pub mod embassy;
74pub mod error;
75pub mod logging;
76pub mod object;
77#[cfg(CONFIG_RUST_ALLOC)]
78pub mod simpletls;
79pub mod sync;
80pub mod sys;
81pub mod thread;
82pub mod time;
83#[cfg(CONFIG_RUST_ALLOC)]
84pub mod timer;
85#[cfg(CONFIG_RUST_ALLOC)]
86pub mod work;
87
88pub use error::{Error, Result};
89
90pub use logging::set_logger;
91
92/// Re-exported for local macro use.
93pub use paste::paste;
94
95/// Re-export the proc macros.
96pub use zephyr_macros::thread;
97
98// Bring in the generated kconfig module
99pub mod kconfig {
100    //! Zephyr Kconfig values.
101    //!
102    //! This module contains an auto-generated set of constants corresponding to the values of
103    //! various Kconfig values during the build.
104    //!
105    //! **Note**: Unless you are viewing docs generated for a specific build, the values below are
106    //! unlikely to directly correspond to those in a given build.
107
108    // Don't enforce doc comments on the bindgen, as it isn't enforced within Zephyr.
109    #![allow(missing_docs)]
110
111    include!(concat!(env!("OUT_DIR"), "/kconfig.rs"));
112}
113
114pub mod devicetree {
115    //! Zephyr device tree
116    //!
117    //! This is an auto-generated module that represents the device tree for a given build.  The
118    //! hierarchy here should match the device tree, with an additional top-level module "labels"
119    //! that contains submodules for all of the labels.
120    //!
121    //! **Note**: Unless you are viewing docs generated for a specific build, the values below are
122    //! unlikely to directly correspond to those in a given build.
123
124    // Don't enforce doc comments on the generated device tree.
125    #![allow(missing_docs)]
126    // Allow nodes to have non-snake-case names.  This comes from addresses in the node names, which
127    // usually use uppercase.
128    #![allow(non_snake_case)]
129
130    include!(concat!(env!("OUT_DIR"), "/devicetree.rs"));
131}
132
133// Ensure that Rust is enabled.
134#[cfg(not(CONFIG_RUST))]
135compile_error!("CONFIG_RUST must be set to build Rust in Zephyr");
136
137// Printk is provided if it is configured into the build.
138#[cfg(CONFIG_PRINTK)]
139pub mod printk;
140
141use core::panic::PanicInfo;
142
143/// Override rust's panic.  This simplistic initial version just hangs in a loop.
144#[panic_handler]
145fn panic(info: &PanicInfo) -> ! {
146    #[cfg(CONFIG_PRINTK)]
147    {
148        printkln!("panic: {}", info);
149    }
150    let _ = info;
151
152    // Call into the wrapper for the system panic function.
153    unsafe {
154        extern "C" {
155            fn rust_panic_wrap() -> !;
156        }
157        rust_panic_wrap();
158    }
159}
160
161/// Re-export of zephyr-sys as `zephyr::raw`.
162pub mod raw {
163    pub use zephyr_sys::*;
164}
165
166/// Provide symbols used by macros in a crate-local namespace.
167#[doc(hidden)]
168pub mod _export {
169    pub use core::format_args;
170
171    use crate::{object::StaticKernelObject, sys::thread::StaticThreadStack};
172
173    /// Type alias for the thread stack kernel object.
174    pub type KStaticThreadStack = StaticKernelObject<StaticThreadStack>;
175}
176
177// Mark this as `pub` so the docs can be read.
178// If allocation has been requested, provide the allocator.
179#[cfg(CONFIG_RUST_ALLOC)]
180pub mod alloc_impl;
181
182#[cfg(CONFIG_RUST_ALLOC)]
183pub mod task {
184    //! Provides the portable-atomic version of `alloc::task::Wake`, which uses the compatible
185    //! versionm of Arc.
186
187    pub use portable_atomic_util::task::Wake;
188}