Skip to content

Commit

Permalink
Implement try-init feature
Browse files Browse the repository at this point in the history
  • Loading branch information
speelbarrow committed Nov 27, 2024
1 parent cfb83b1 commit 58ceaff
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 0 deletions.
4 changes: 4 additions & 0 deletions esp-hal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ esp-synopsys-usb-otg = { version = "0.4.2", optional = true, features = ["fs
fugit = "0.3.7"
log = { version = "0.4.22", optional = true }
nb = "1.1.0"
once_cell = { version = "1.20.2", optional = true, default-features = false, features = ["race"] }
paste = "1.0.15"
portable-atomic = { version = "1.9.0", default-features = false }
procmacros = { version = "0.15.0", package = "esp-hal-procmacros", path = "../esp-hal-procmacros" }
Expand Down Expand Up @@ -152,6 +153,9 @@ octal-psram = []
# This feature is intended for testing; you probably don't want to enable it:
ci = ["defmt", "bluetooth"]

# Enable `try_init` -- requires once_cell
try-init = ["once_cell"]

[lints.clippy]
mixed_attributes_style = "allow"

Expand Down
15 changes: 15 additions & 0 deletions esp-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -559,3 +559,18 @@ pub fn init(config: Config) -> Peripherals {

peripherals
}

/// Attempts to initialize the system.
///
/// If [`init`] has already been executed, returns [`None`].
/// (This check is [thread-safe](once_cell::race::OnceBool))
///
/// Otherwise, initializes and returns the [`Peripherals`].
#[cfg(feature = "try-init")]
pub fn try_init(config: Config) -> Option<Peripherals> {
if !Peripherals::initialized() {
Some(init(config))
} else {
None
}
}
19 changes: 19 additions & 0 deletions esp-hal/src/peripheral.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ mod peripheral_macros {
),* $(,)?
]
) => {
#[cfg(feature = "try-init")]
use once_cell::race::OnceBool;

/// Contains the generated peripherals which implement [`Peripheral`]
mod peripherals {
Expand Down Expand Up @@ -293,8 +295,25 @@ mod peripheral_macros {
}

impl Peripherals {
#[cfg(feature = "try-init")]
const INITIALIZED: OnceBool = OnceBool::new();

#[cfg(feature = "try-init")]
pub(crate) fn initialized() -> bool {
Self::INITIALIZED.get().is_some()
}

/// Returns all the peripherals *once*
#[inline]
#[cfg(feature = "try-init")]
pub(crate) fn take() -> Self {
if let Ok(_) = Self::INITIALIZED.set(true) {
unsafe { Self::steal() }
} else {
panic!("init called more than once!")
}
}
#[cfg(not(feature = "try-init"))]
pub(crate) fn take() -> Self {
#[no_mangle]
static mut _ESP_HAL_DEVICE_PERIPHERALS: bool = false;
Expand Down

0 comments on commit 58ceaff

Please sign in to comment.