Skip to main content

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
71// Allow this crate to refer to itself by name
72extern crate self as zephyr;
73
74pub mod align;
75#[cfg(all(feature = "async-drivers", CONFIG_RUST_BLOCKING_POOL))]
76pub mod blocking;
77pub mod device;
78pub mod embassy;
79pub mod error;
80pub mod logging;
81pub mod object;
82#[cfg(CONFIG_RUST_ALLOC)]
83pub mod simpletls;
84pub mod sync;
85pub mod sys;
86pub mod thread;
87pub mod time;
88#[cfg(CONFIG_RUST_ALLOC)]
89pub mod timer;
90#[cfg(CONFIG_RUST_ALLOC)]
91pub mod work;
92
93pub use error::{Error, Result};
94
95pub use logging::set_logger;
96
97/// Re-exported for local macro use.
98pub use paste::paste;
99
100/// Re-export the proc macros.
101pub use zephyr_macros::thread;
102
103// Bring in the generated kconfig module
104pub mod kconfig {
105    //! Zephyr Kconfig values.
106    //!
107    //! This module contains an auto-generated set of constants corresponding to the values of
108    //! various Kconfig values during the build.
109    //!
110    //! **Note**: Unless you are viewing docs generated for a specific build, the values below are
111    //! unlikely to directly correspond to those in a given build.
112
113    // Don't enforce doc comments on the bindgen, as it isn't enforced within Zephyr.
114    #![allow(missing_docs)]
115
116    include!(concat!(env!("OUT_DIR"), "/kconfig.rs"));
117}
118
119pub mod devicetree {
120    //! Zephyr device tree
121    //!
122    //! This is an auto-generated module that represents the device tree for a given build.  The
123    //! hierarchy here should match the device tree, with an additional top-level module "labels"
124    //! that contains submodules for all of the labels.
125    //!
126    //! **Note**: Unless you are viewing docs generated for a specific build, the values below are
127    //! unlikely to directly correspond to those in a given build.
128
129    // Don't enforce doc comments on the generated device tree.
130    #![allow(missing_docs)]
131    // Allow nodes to have non-snake-case names.  This comes from addresses in the node names, which
132    // usually use uppercase.
133    #![allow(non_snake_case)]
134
135    include!(concat!(env!("OUT_DIR"), "/devicetree.rs"));
136}
137
138// Ensure that Rust is enabled.
139#[cfg(not(CONFIG_RUST))]
140compile_error!("CONFIG_RUST must be set to build Rust in Zephyr");
141
142// Printk is provided if it is configured into the build.
143#[cfg(CONFIG_PRINTK)]
144pub mod printk;
145
146use core::panic::PanicInfo;
147
148/// Override rust's panic.  This simplistic initial version just hangs in a loop.
149#[panic_handler]
150fn panic(info: &PanicInfo) -> ! {
151    #[cfg(CONFIG_PRINTK)]
152    {
153        printkln!("panic: {}", info);
154    }
155    let _ = info;
156
157    // Call into the wrapper for the system panic function.
158    unsafe {
159        extern "C" {
160            fn rust_panic_wrap() -> !;
161        }
162        rust_panic_wrap();
163    }
164}
165
166/// Re-export of zephyr-sys as `zephyr::raw`.
167pub mod raw {
168    pub use zephyr_sys::*;
169}
170
171/// Provide symbols used by macros in a crate-local namespace.
172#[doc(hidden)]
173pub mod _export {
174    pub use core::format_args;
175
176    use crate::{object::StaticKernelObject, sys::thread::StaticThreadStack};
177
178    /// Type alias for the thread stack kernel object.
179    pub type KStaticThreadStack = StaticKernelObject<StaticThreadStack>;
180}
181
182// Mark this as `pub` so the docs can be read.
183// If allocation has been requested, provide the allocator.
184#[cfg(CONFIG_RUST_ALLOC)]
185pub mod alloc_impl;
186
187#[cfg(CONFIG_RUST_ALLOC)]
188pub mod task {
189    //! Provides the portable-atomic version of `alloc::task::Wake`, which uses the compatible
190    //! versionm of Arc.
191
192    pub use portable_atomic_util::task::Wake;
193}