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}