Skip to main content

rpi_hal_embassy/
lib.rs

1//! [Embassy](https://embassy.dev) support for Raspberry Pi boards using
2//! the BCM2836/BCM2837 SoC (Pi 2, Pi 3), on top of the `rpi-hal` crate.
3//!
4//! Provides the two platform pieces Embassy needs and cannot supply
5//! itself: an `embassy-time` driver over the BCM System Timer, and a
6//! thread-mode executor for AArch32 and AArch64.
7//!
8//! This is a separate crate from `rpi-hal` rather than a feature of it
9//! because an `embassy-time` driver is installed by *linkage*: the
10//! `time_driver_impl!` macro defines `#[unsafe(no_mangle)]` symbols that
11//! `embassy-time` resolves against, and a program links only if exactly
12//! one driver exists in its crate graph. Behind a feature on the HAL, any
13//! dependency enabling that feature would force this driver onto the whole
14//! program and conflict with an application supplying its own — an opt-in
15//! that cannot be opted out of.
16//!
17//! # What an application must provide
18//!
19//! - **A `critical-section` implementation**, which `rpi-hal`'s `rt`
20//!   feature provides. The timer queue is guarded by one.
21//! - **`rpi-hal`'s `mmu` feature** (on by default). The executor's run
22//!   queue is built on atomic compare-exchange, and `ldrex`/`strex` are
23//!   UNPREDICTABLE until RAM is mapped as cacheable Normal memory.
24//! - **Interrupt dispatch.** `rpi-hal` leaves `__irq_handler` to the
25//!   application, so this crate cannot claim it; the application routes
26//!   the System Timer's interrupt here from its own handler.
27
28#![no_std]
29#![deny(missing_docs)]
30
31/// `embassy-net` adapter over `rpi-hal`'s USB-Ethernet drivers, whichever
32/// chip the board has — see the module's own documentation for the
33/// interrupt wiring an application must provide.
34#[cfg(feature = "embassy-net-driver")]
35pub mod ethernet;
36/// Thread-mode executor for AArch32 and AArch64 — see the module's own
37/// documentation for why this isn't one of `embassy-executor`'s backends.
38pub mod executor;
39/// Getting interrupts to the code waiting on them — see [`irq::dispatch`],
40/// and the `irq-dispatch` feature for the case where an application has no
41/// sources of its own.
42pub mod irq;
43/// The LAN9514 spelling of [`ethernet`], kept so existing boards compile
44/// unchanged.
45#[cfg(feature = "embassy-net-driver")]
46pub mod lan9514;
47/// `embassy-time` driver over the BCM System Timer — see the module's own
48/// documentation for the interrupt wiring an application must provide.
49pub mod time_driver;
50/// `embassy-net` adapter over `rpi-hal`'s Wi-Fi driver — see the module's
51/// own documentation for why its runner polls where `lan9514`'s does not.
52#[cfg(feature = "wifi")]
53pub mod wifi;
54
55/// Re-exported at the crate root because that is the path
56/// `#[embassy_executor::main(executor = "rpi_hal_embassy::Executor")]`
57/// expects to find it at.
58pub use executor::Executor;
59
60/// `embassy-net-driver-channel`, re-exported.
61///
62/// The queue pair both network adapters hand the stack is this crate's
63/// `Device`, and [`ethernet::attach`]/[`wifi::attach`] take its `Runner`.
64/// A board that owns its own queue pair — one that picks between Ethernet
65/// and Wi-Fi at startup, say — needs `channel::State` and `channel::new`
66/// to build it.
67///
68/// Re-exported rather than left for the board to depend on directly, so
69/// there is no way to end up with two incompatible versions of a type that
70/// crosses this crate's API. The version is whatever this crate was built
71/// against.
72#[cfg(any(feature = "embassy-net-driver", feature = "wifi"))]
73pub use embassy_net_driver_channel as channel;