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}