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 /// An expanded property in the devicetree.
136 #[derive(Debug)]
137 pub enum Value {
138 /// A string value.
139 String(&'static str),
140 /// An arbitrary byte sequence.
141 Bytes(&'static [u8]),
142 /// A sequence of devicetree cells (numbers, phandles, or GPIO references).
143 Words(&'static [Word]),
144 /// A phandle value. For now, this is just the name, since we can't dynamically reference a module.
145 Phandle(&'static str),
146 }
147
148 // A single word within a devicetree property.
149 #[derive(Debug)]
150 pub enum Word {
151 // A 32 bit number.
152 Number(u32),
153 /// A phandle value. For now, this is just the name, since we can't dynamically reference a module.
154 Phandle(&'static str),
155 /// A specific GPIO value.
156 Gpio(&'static str, &'static [u32]),
157 }
158
159 include!(concat!(env!("OUT_DIR"), "/devicetree.rs"));
160}
161
162// Ensure that Rust is enabled.
163#[cfg(not(CONFIG_RUST))]
164compile_error!("CONFIG_RUST must be set to build Rust in Zephyr");
165
166// Printk is provided if it is configured into the build.
167#[cfg(CONFIG_PRINTK)]
168pub mod printk;
169
170/// Re-export of zephyr-sys as `zephyr::raw`.
171pub mod raw {
172 pub use zephyr_sys::*;
173}
174
175/// Provide symbols used by macros in a crate-local namespace.
176#[doc(hidden)]
177pub mod _export {
178 pub use core::format_args;
179
180 use crate::{object::StaticKernelObject, sys::thread::StaticThreadStack};
181
182 /// Type alias for the thread stack kernel object.
183 pub type KStaticThreadStack = StaticKernelObject<StaticThreadStack>;
184}
185
186// Mark this as `pub` so the docs can be read.
187// If allocation has been requested, provide the allocator.
188#[cfg(CONFIG_RUST_ALLOC)]
189pub mod alloc_impl;
190
191#[cfg(CONFIG_RUST_ALLOC)]
192pub mod task {
193 //! Provides the portable-atomic version of `alloc::task::Wake`, which uses the compatible
194 //! versionm of Arc.
195
196 pub use portable_atomic_util::task::Wake;
197}