diff --git a/embassy-cortex-m/src/executor.rs b/embassy-cortex-m/src/executor.rs index 80c452f8..0d1745d8 100644 --- a/embassy-cortex-m/src/executor.rs +++ b/embassy-cortex-m/src/executor.rs @@ -71,7 +71,7 @@ impl InterruptExecutor { /// Executor instance in a place where it'll live forever and grants you mutable /// access. There's a few ways to do this: /// - /// - a [Forever](embassy_util::Forever) (safe) + /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe) /// - a `static mut` (unsafe) /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) pub fn start(&'static mut self) -> SendSpawner { diff --git a/embassy-embedded-hal/src/shared_bus/asynch/i2c.rs b/embassy-embedded-hal/src/shared_bus/asynch/i2c.rs index bd023fb6..dc483b82 100644 --- a/embassy-embedded-hal/src/shared_bus/asynch/i2c.rs +++ b/embassy-embedded-hal/src/shared_bus/asynch/i2c.rs @@ -7,12 +7,12 @@ //! use embassy_util::mutex::Mutex; //! use embassy_util::blocking_mutex::raw::ThreadModeRawMutex; //! -//! static I2C_BUS: Forever>> = Forever::new(); +//! static I2C_BUS: StaticCell>> = StaticCell::new(); //! let config = twim::Config::default(); //! let irq = interrupt::take!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); //! let i2c = Twim::new(p.TWISPI0, irq, p.P0_03, p.P0_04, config); //! let i2c_bus = Mutex::::new(i2c); -//! let i2c_bus = I2C_BUS.put(i2c_bus); +//! let i2c_bus = I2C_BUS.init(i2c_bus); //! //! // Device 1, using embedded-hal-async compatible driver for QMC5883L compass //! let i2c_dev1 = I2cDevice::new(i2c_bus); diff --git a/embassy-embedded-hal/src/shared_bus/asynch/spi.rs b/embassy-embedded-hal/src/shared_bus/asynch/spi.rs index caa37f6f..bb419d6a 100644 --- a/embassy-embedded-hal/src/shared_bus/asynch/spi.rs +++ b/embassy-embedded-hal/src/shared_bus/asynch/spi.rs @@ -7,13 +7,13 @@ //! use embassy_util::mutex::Mutex; //! use embassy_util::blocking_mutex::raw::ThreadModeRawMutex; //! -//! static SPI_BUS: Forever>> = Forever::new(); +//! static SPI_BUS: StaticCell>> = StaticCell::new(); //! let mut config = spim::Config::default(); //! config.frequency = spim::Frequency::M32; //! let irq = interrupt::take!(SPIM3); //! let spi = spim::Spim::new_txonly(p.SPI3, irq, p.P0_15, p.P0_18, config); //! let spi_bus = Mutex::::new(spi); -//! let spi_bus = SPI_BUS.put(spi_bus); +//! let spi_bus = SPI_BUS.init(spi_bus); //! //! // Device 1, using embedded-hal-async compatible driver for ST7735 LCD display //! let cs_pin1 = Output::new(p.P0_24, Level::Low, OutputDrive::Standard); diff --git a/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs b/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs index 1fc343d1..837312e8 100644 --- a/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs +++ b/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs @@ -6,11 +6,11 @@ //! use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice; //! use embassy_util::blocking_mutex::{NoopMutex, raw::NoopRawMutex}; //! -//! static I2C_BUS: Forever>>> = Forever::new(); +//! static I2C_BUS: StaticCell>>> = StaticCell::new(); //! let irq = interrupt::take!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0); //! let i2c = Twim::new(p.TWISPI0, irq, p.P0_03, p.P0_04, Config::default()); //! let i2c_bus = NoopMutex::new(RefCell::new(i2c)); -//! let i2c_bus = I2C_BUS.put(i2c_bus); +//! let i2c_bus = I2C_BUS.init(i2c_bus); //! //! let i2c_dev1 = I2cDevice::new(i2c_bus); //! let mpu = Mpu6050::new(i2c_dev1); diff --git a/embassy-embedded-hal/src/shared_bus/blocking/spi.rs b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs index a6132659..a48d9183 100644 --- a/embassy-embedded-hal/src/shared_bus/blocking/spi.rs +++ b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs @@ -6,11 +6,11 @@ //! use embassy_embedded_hal::shared_bus::blocking::spi::SpiDevice; //! use embassy_util::blocking_mutex::{NoopMutex, raw::NoopRawMutex}; //! -//! static SPI_BUS: Forever>>> = Forever::new(); +//! static SPI_BUS: StaticCell>>> = StaticCell::new(); //! let irq = interrupt::take!(SPIM3); //! let spi = Spim::new_txonly(p.SPI3, irq, p.P0_15, p.P0_18, Config::default()); //! let spi_bus = NoopMutex::new(RefCell::new(spi)); -//! let spi_bus = SPI_BUS.put(spi_bus); +//! let spi_bus = SPI_BUS.init(spi_bus); //! //! // Device 1, using embedded-hal compatible driver for ST7735 LCD display //! let cs_pin1 = Output::new(p.P0_24, Level::Low, OutputDrive::Standard); diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index 7d5c4a04..184e770c 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml @@ -44,6 +44,7 @@ embassy-time = { version = "0.1.0", path = "../embassy-time", optional = true} atomic-polyfill = "1.0.1" critical-section = "1.1" cfg-if = "1.0.0" +static_cell = "1.0" # WASM dependencies wasm-bindgen = { version = "0.2.76", features = ["nightly"], optional = true } diff --git a/embassy-executor/src/arch/cortex_m.rs b/embassy-executor/src/arch/cortex_m.rs index d6e758df..4b27a264 100644 --- a/embassy-executor/src/arch/cortex_m.rs +++ b/embassy-executor/src/arch/cortex_m.rs @@ -41,7 +41,7 @@ impl Executor { /// Executor instance in a place where it'll live forever and grants you mutable /// access. There's a few ways to do this: /// - /// - a [Forever](crate::util::Forever) (safe) + /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe) /// - a `static mut` (unsafe) /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) /// diff --git a/embassy-executor/src/arch/riscv32.rs b/embassy-executor/src/arch/riscv32.rs index 7a7d5698..2a4b006d 100644 --- a/embassy-executor/src/arch/riscv32.rs +++ b/embassy-executor/src/arch/riscv32.rs @@ -43,7 +43,7 @@ impl Executor { /// Executor instance in a place where it'll live forever and grants you mutable /// access. There's a few ways to do this: /// - /// - a [Forever](crate::util::Forever) (safe) + /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe) /// - a `static mut` (unsafe) /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) /// diff --git a/embassy-executor/src/arch/std.rs b/embassy-executor/src/arch/std.rs index b93ab8a7..701f0eb1 100644 --- a/embassy-executor/src/arch/std.rs +++ b/embassy-executor/src/arch/std.rs @@ -40,7 +40,7 @@ impl Executor { /// Executor instance in a place where it'll live forever and grants you mutable /// access. There's a few ways to do this: /// - /// - a [Forever](crate::util::Forever) (safe) + /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe) /// - a `static mut` (unsafe) /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) /// diff --git a/embassy-executor/src/arch/wasm.rs b/embassy-executor/src/arch/wasm.rs index 9d5aa31e..98091cfb 100644 --- a/embassy-executor/src/arch/wasm.rs +++ b/embassy-executor/src/arch/wasm.rs @@ -59,7 +59,7 @@ impl Executor { /// Executor instance in a place where it'll live forever and grants you mutable /// access. There's a few ways to do this: /// - /// - a [Forever](crate::util::Forever) (safe) + /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe) /// - a `static mut` (unsafe) /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) pub fn start(&'static mut self, init: impl FnOnce(Spawner)) { diff --git a/embassy-executor/src/arch/xtensa.rs b/embassy-executor/src/arch/xtensa.rs index 20bd7b8a..f908aaa7 100644 --- a/embassy-executor/src/arch/xtensa.rs +++ b/embassy-executor/src/arch/xtensa.rs @@ -43,7 +43,7 @@ impl Executor { /// Executor instance in a place where it'll live forever and grants you mutable /// access. There's a few ways to do this: /// - /// - a [Forever](crate::util::Forever) (safe) + /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe) /// - a `static mut` (unsafe) /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) /// diff --git a/embassy-executor/src/lib.rs b/embassy-executor/src/lib.rs index 93f2eaa6..e4cbd04b 100644 --- a/embassy-executor/src/lib.rs +++ b/embassy-executor/src/lib.rs @@ -67,3 +67,9 @@ pub mod raw; mod spawner; pub use spawner::*; + +/// Do not use. Used for macros and HALs only. Not covered by semver guarantees. +#[doc(hidden)] +pub mod _export { + pub use static_cell::StaticCell; +} diff --git a/embassy-macros/src/macros/main.rs b/embassy-macros/src/macros/main.rs index 52987d7d..afe9bd3e 100644 --- a/embassy-macros/src/macros/main.rs +++ b/embassy-macros/src/macros/main.rs @@ -34,8 +34,8 @@ pub fn run(args: syn::AttributeArgs, f: syn::ItemFn) -> Result Result<(), wasm_bindgen::JsValue> { - static EXECUTOR: ::embassy_util::Forever<::embassy_executor::Executor> = ::embassy_util::Forever::new(); - let executor = EXECUTOR.put(::embassy_executor::Executor::new()); + static EXECUTOR: ::embassy_executor::_export::StaticCell<::embassy_executor::Executor> = ::embassy_executor::_export::StaticCell::new(); + let executor = EXECUTOR.init(::embassy_executor::Executor::new()); executor.start(|spawner| { spawner.spawn(__embassy_main(spawner)).unwrap(); diff --git a/embassy-util/Cargo.toml b/embassy-util/Cargo.toml index d4708d73..b54a58b4 100644 --- a/embassy-util/Cargo.toml +++ b/embassy-util/Cargo.toml @@ -31,3 +31,4 @@ futures-util = { version = "0.3.17", features = [ "channel" ] } # Enable critical-section implementation for std, for tests critical-section = { version = "1.1", features = ["std"] } +static_cell = "1.0" diff --git a/embassy-util/src/channel/mpmc.rs b/embassy-util/src/channel/mpmc.rs index 535f77e6..263f29bf 100644 --- a/embassy-util/src/channel/mpmc.rs +++ b/embassy-util/src/channel/mpmc.rs @@ -471,10 +471,10 @@ mod tests { use futures_executor::ThreadPool; use futures_timer::Delay; use futures_util::task::SpawnExt; + use static_cell::StaticCell; use super::*; use crate::blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex}; - use crate::Forever; fn capacity(c: &ChannelState) -> usize { c.queue.capacity() - c.queue.len() @@ -549,8 +549,8 @@ mod tests { async fn receiver_receives_given_try_send_async() { let executor = ThreadPool::new().unwrap(); - static CHANNEL: Forever> = Forever::new(); - let c = &*CHANNEL.put(Channel::new()); + static CHANNEL: StaticCell> = StaticCell::new(); + let c = &*CHANNEL.init(Channel::new()); let c2 = c; assert!(executor .spawn(async move { @@ -571,8 +571,8 @@ mod tests { async fn senders_sends_wait_until_capacity() { let executor = ThreadPool::new().unwrap(); - static CHANNEL: Forever> = Forever::new(); - let c = &*CHANNEL.put(Channel::new()); + static CHANNEL: StaticCell> = StaticCell::new(); + let c = &*CHANNEL.init(Channel::new()); assert!(c.try_send(1).is_ok()); let c2 = c; diff --git a/embassy-util/src/forever.rs b/embassy-util/src/forever.rs deleted file mode 100644 index 4f369821..00000000 --- a/embassy-util/src/forever.rs +++ /dev/null @@ -1,95 +0,0 @@ -use core::cell::UnsafeCell; -use core::mem::MaybeUninit; - -use atomic_polyfill::{AtomicBool, Ordering}; - -/// Type with static lifetime that may be written to once at runtime. -/// -/// This may be used to initialize static objects at runtime, typically in the init routine. -/// This is useful for objects such as Embassy's RTC, which cannot be initialized in a const -/// context. -/// -/// Note: IF a global mutable variable is desired, use a CriticalSectionMutex or ThreadModeMutex instead. -/// -/// ``` -/// use embassy_util::Forever; -/// // Using an integer for the sake of keeping this example self-contained, -/// // see https://github.com/embassy-rs/embassy/wiki/Getting-Started for a more "proper" example. -/// static SOME_INT: Forever =Forever::new(); -/// -/// // put returns a mutable pointer to the object stored in the forever, which may then be passed -/// // around. -/// let mut x = SOME_INT.put(42); -/// assert_eq!(*x, 42); -/// ``` -pub struct Forever { - used: AtomicBool, - t: UnsafeCell>, -} - -unsafe impl Send for Forever {} -unsafe impl Sync for Forever {} - -impl Forever { - /// Create a new `Forever`. - #[inline(always)] - pub const fn new() -> Self { - Self { - used: AtomicBool::new(false), - t: UnsafeCell::new(MaybeUninit::uninit()), - } - } - - /// Store a value in this `Forever`, returning a mutable reference to it. - /// - /// Using this method, the compiler usually constructs `val` in the stack and then moves - /// it into the `Forever`. If `T` is big, this is likely to cause stack overflows. - /// Considering using [`Signal::put_with`] instead, which will construct it in-place inside the `Forever`. - /// - /// # Panics - /// - /// Panics if this `Forever` already has a value stored in it. - #[inline(always)] - #[allow(clippy::mut_from_ref)] - pub fn put(&'static self, val: T) -> &'static mut T { - self.put_with(|| val) - } - - /// Store the closure return value in this `Forever`, returning a mutable reference to it. - /// - /// The advantage over [`Forever::put`] is that this method allows the closure to construct - /// the `T` value in-place directly inside the `Forever`, saving stack space. - /// - /// # Panics - /// - /// Panics if this `Forever` already has a value stored in it. - #[inline(always)] - #[allow(clippy::mut_from_ref)] - pub fn put_with(&'static self, val: impl FnOnce() -> T) -> &'static mut T { - if self - .used - .compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed) - .is_err() - { - panic!("Forever.put() called multiple times"); - } - - let p: &'static mut MaybeUninit = unsafe { &mut *self.t.get() }; - p.write(val()) - } - - /// Unsafely get a mutable reference to the contents of this Forever. - /// - /// # Safety - /// - /// This is undefined behavior if: - /// - /// - The `Forever` has not been initialized yet (with `put' or `put_with`), or - /// - A reference to the contents (mutable or not) already exists. - #[inline(always)] - #[allow(clippy::mut_from_ref)] - pub unsafe fn steal(&self) -> &mut T { - let p: &mut MaybeUninit = &mut *self.t.get(); - p.assume_init_mut() - } -} diff --git a/embassy-util/src/lib.rs b/embassy-util/src/lib.rs index 110c7281..8ec3300d 100644 --- a/embassy-util/src/lib.rs +++ b/embassy-util/src/lib.rs @@ -16,10 +16,8 @@ pub mod mutex; pub mod pipe; pub mod waitqueue; -mod forever; mod select; mod yield_now; -pub use forever::*; pub use select::*; pub use yield_now::*; diff --git a/embassy-util/src/pipe.rs b/embassy-util/src/pipe.rs index 9c20aeef..d85b843e 100644 --- a/embassy-util/src/pipe.rs +++ b/embassy-util/src/pipe.rs @@ -461,10 +461,10 @@ mod io_impls { mod tests { use futures_executor::ThreadPool; use futures_util::task::SpawnExt; + use static_cell::StaticCell; use super::*; use crate::blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex}; - use crate::Forever; fn capacity(c: &PipeState) -> usize { N - c.buffer.len() @@ -528,8 +528,8 @@ mod tests { async fn receiver_receives_given_try_write_async() { let executor = ThreadPool::new().unwrap(); - static CHANNEL: Forever> = Forever::new(); - let c = &*CHANNEL.put(Pipe::new()); + static CHANNEL: StaticCell> = StaticCell::new(); + let c = &*CHANNEL.init(Pipe::new()); let c2 = c; let f = async move { assert_eq!(c2.try_write(&[42]), Ok(1)); diff --git a/examples/nrf/Cargo.toml b/examples/nrf/Cargo.toml index 2fcc3122..17f29b8f 100644 --- a/examples/nrf/Cargo.toml +++ b/examples/nrf/Cargo.toml @@ -22,6 +22,7 @@ embedded-io = "0.3.0" defmt = "0.3" defmt-rtt = "0.3" +static_cell = "1.0" cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } cortex-m-rt = "0.7.0" panic-probe = { version = "0.3", features = ["print-defmt"] } diff --git a/examples/nrf/src/bin/channel_sender_receiver.rs b/examples/nrf/src/bin/channel_sender_receiver.rs index c9c458ae..d250b6a5 100644 --- a/examples/nrf/src/bin/channel_sender_receiver.rs +++ b/examples/nrf/src/bin/channel_sender_receiver.rs @@ -8,7 +8,7 @@ use embassy_nrf::gpio::{AnyPin, Level, Output, OutputDrive, Pin}; use embassy_time::{Duration, Timer}; use embassy_util::blocking_mutex::raw::NoopRawMutex; use embassy_util::channel::mpmc::{Channel, Receiver, Sender}; -use embassy_util::Forever; +use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; enum LedState { @@ -16,7 +16,7 @@ enum LedState { Off, } -static CHANNEL: Forever> = Forever::new(); +static CHANNEL: StaticCell> = StaticCell::new(); #[embassy_executor::task] async fn send_task(sender: Sender<'static, NoopRawMutex, LedState, 1>) { @@ -43,7 +43,7 @@ async fn recv_task(led: AnyPin, receiver: Receiver<'static, NoopRawMutex, LedSta #[embassy_executor::main] async fn main(spawner: Spawner) { let p = embassy_nrf::init(Default::default()); - let channel = CHANNEL.put(Channel::new()); + let channel = CHANNEL.init(Channel::new()); unwrap!(spawner.spawn(send_task(channel.sender()))); unwrap!(spawner.spawn(recv_task(p.P0_13.degrade(), channel.receiver()))); diff --git a/examples/nrf/src/bin/multiprio.rs b/examples/nrf/src/bin/multiprio.rs index b653689a..25806ae4 100644 --- a/examples/nrf/src/bin/multiprio.rs +++ b/examples/nrf/src/bin/multiprio.rs @@ -63,7 +63,7 @@ use embassy_nrf::executor::{Executor, InterruptExecutor}; use embassy_nrf::interrupt; use embassy_nrf::interrupt::InterruptExt; use embassy_time::{Duration, Instant, Timer}; -use embassy_util::Forever; +use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::task] @@ -108,9 +108,9 @@ async fn run_low() { } } -static EXECUTOR_HIGH: Forever> = Forever::new(); -static EXECUTOR_MED: Forever> = Forever::new(); -static EXECUTOR_LOW: Forever = Forever::new(); +static EXECUTOR_HIGH: StaticCell> = StaticCell::new(); +static EXECUTOR_MED: StaticCell> = StaticCell::new(); +static EXECUTOR_LOW: StaticCell = StaticCell::new(); #[entry] fn main() -> ! { @@ -121,19 +121,19 @@ fn main() -> ! { // High-priority executor: SWI1_EGU1, priority level 6 let irq = interrupt::take!(SWI1_EGU1); irq.set_priority(interrupt::Priority::P6); - let executor = EXECUTOR_HIGH.put(InterruptExecutor::new(irq)); + let executor = EXECUTOR_HIGH.init(InterruptExecutor::new(irq)); let spawner = executor.start(); unwrap!(spawner.spawn(run_high())); // Medium-priority executor: SWI0_EGU0, priority level 7 let irq = interrupt::take!(SWI0_EGU0); irq.set_priority(interrupt::Priority::P7); - let executor = EXECUTOR_MED.put(InterruptExecutor::new(irq)); + let executor = EXECUTOR_MED.init(InterruptExecutor::new(irq)); let spawner = executor.start(); unwrap!(spawner.spawn(run_med())); // Low priority executor: runs in thread mode, using WFE/SEV - let executor = EXECUTOR_LOW.put(Executor::new()); + let executor = EXECUTOR_LOW.init(Executor::new()); executor.run(|spawner| { unwrap!(spawner.spawn(run_low())); }); diff --git a/examples/nrf/src/bin/raw_spawn.rs b/examples/nrf/src/bin/raw_spawn.rs index 415579be..1b067f5e 100644 --- a/examples/nrf/src/bin/raw_spawn.rs +++ b/examples/nrf/src/bin/raw_spawn.rs @@ -8,7 +8,7 @@ use defmt::{info, unwrap}; use embassy_executor::raw::TaskStorage; use embassy_executor::Executor; use embassy_time::{Duration, Timer}; -use embassy_util::Forever; +use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; async fn run1() { @@ -25,14 +25,14 @@ async fn run2() { } } -static EXECUTOR: Forever = Forever::new(); +static EXECUTOR: StaticCell = StaticCell::new(); #[entry] fn main() -> ! { info!("Hello World!"); let _p = embassy_nrf::init(Default::default()); - let executor = EXECUTOR.put(Executor::new()); + let executor = EXECUTOR.init(Executor::new()); let run1_task = TaskStorage::new(); let run2_task = TaskStorage::new(); diff --git a/examples/nrf/src/bin/usb_ethernet.rs b/examples/nrf/src/bin/usb_ethernet.rs index f0a87031..d427f756 100644 --- a/examples/nrf/src/bin/usb_ethernet.rs +++ b/examples/nrf/src/bin/usb_ethernet.rs @@ -18,17 +18,17 @@ use embassy_usb::{Builder, Config, UsbDevice}; use embassy_usb_ncm::{CdcNcmClass, Receiver, Sender, State}; use embassy_util::blocking_mutex::raw::ThreadModeRawMutex; use embassy_util::channel::mpmc::Channel; -use embassy_util::Forever; use embedded_io::asynch::{Read, Write}; +use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; type MyDriver = Driver<'static, peripherals::USBD, PowerUsb>; -macro_rules! forever { +macro_rules! singleton { ($val:expr) => {{ type T = impl Sized; - static FOREVER: Forever = Forever::new(); - FOREVER.put_with(move || $val) + static STATIC_CELL: StaticCell = StaticCell::new(); + STATIC_CELL.init_with(move || $val) }}; } @@ -116,7 +116,7 @@ async fn main(spawner: Spawner) { control_buf: [u8; 128], serial_state: State<'static>, } - let res: &mut Resources = forever!(Resources { + let res: &mut Resources = singleton!(Resources { device_descriptor: [0; 256], config_descriptor: [0; 256], bos_descriptor: [0; 256], @@ -174,10 +174,10 @@ async fn main(spawner: Spawner) { // Init network stack let device = Device { mac_addr: our_mac_addr }; - let stack = &*forever!(Stack::new( + let stack = &*singleton!(Stack::new( device, config, - forever!(StackResources::<1, 2, 8>::new()), + singleton!(StackResources::<1, 2, 8>::new()), seed )); diff --git a/examples/nrf/src/bin/usb_serial_multitask.rs b/examples/nrf/src/bin/usb_serial_multitask.rs index 4c1a9308..d62d7e52 100644 --- a/examples/nrf/src/bin/usb_serial_multitask.rs +++ b/examples/nrf/src/bin/usb_serial_multitask.rs @@ -12,7 +12,7 @@ use embassy_nrf::{interrupt, pac, peripherals}; use embassy_usb::driver::EndpointError; use embassy_usb::{Builder, Config, UsbDevice}; use embassy_usb_serial::{CdcAcmClass, State}; -use embassy_util::Forever; +use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; type MyDriver = Driver<'static, peripherals::USBD, PowerUsb>; @@ -67,8 +67,8 @@ async fn main(spawner: Spawner) { control_buf: [u8; 64], serial_state: State<'static>, } - static RESOURCES: Forever = Forever::new(); - let res = RESOURCES.put(Resources { + static RESOURCES: StaticCell = StaticCell::new(); + let res = RESOURCES.init(Resources { device_descriptor: [0; 256], config_descriptor: [0; 256], bos_descriptor: [0; 256], diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml index b7009017..164a2b42 100644 --- a/examples/std/Cargo.toml +++ b/examples/std/Cargo.toml @@ -20,3 +20,4 @@ libc = "0.2.101" clap = { version = "3.0.0-beta.5", features = ["derive"] } rand_core = { version = "0.6.3", features = ["std"] } heapless = { version = "0.7.5", default-features = false } +static_cell = "1.0" diff --git a/examples/std/src/bin/net.rs b/examples/std/src/bin/net.rs index 52860926..9b1450b7 100644 --- a/examples/std/src/bin/net.rs +++ b/examples/std/src/bin/net.rs @@ -4,22 +4,22 @@ use clap::Parser; use embassy_executor::{Executor, Spawner}; use embassy_net::tcp::TcpSocket; use embassy_net::{ConfigStrategy, Ipv4Address, Ipv4Cidr, Stack, StackResources}; -use embassy_util::Forever; use embedded_io::asynch::Write; use heapless::Vec; use log::*; use rand_core::{OsRng, RngCore}; +use static_cell::StaticCell; #[path = "../tuntap.rs"] mod tuntap; use crate::tuntap::TunTapDevice; -macro_rules! forever { +macro_rules! singleton { ($val:expr) => {{ type T = impl Sized; - static FOREVER: Forever = Forever::new(); - FOREVER.put_with(move || $val) + static STATIC_CELL: StaticCell = StaticCell::new(); + STATIC_CELL.init_with(move || $val) }}; } @@ -63,10 +63,10 @@ async fn main_task(spawner: Spawner) { let seed = u64::from_le_bytes(seed); // Init network stack - let stack = &*forever!(Stack::new( + let stack = &*singleton!(Stack::new( device, config, - forever!(StackResources::<1, 2, 8>::new()), + singleton!(StackResources::<1, 2, 8>::new()), seed )); @@ -97,7 +97,7 @@ async fn main_task(spawner: Spawner) { } } -static EXECUTOR: Forever = Forever::new(); +static EXECUTOR: StaticCell = StaticCell::new(); fn main() { env_logger::builder() @@ -106,7 +106,7 @@ fn main() { .format_timestamp_nanos() .init(); - let executor = EXECUTOR.put(Executor::new()); + let executor = EXECUTOR.init(Executor::new()); executor.run(|spawner| { spawner.spawn(main_task(spawner)).unwrap(); }); diff --git a/examples/std/src/bin/net_udp.rs b/examples/std/src/bin/net_udp.rs index 07e11c38..392a97f0 100644 --- a/examples/std/src/bin/net_udp.rs +++ b/examples/std/src/bin/net_udp.rs @@ -4,21 +4,21 @@ use clap::Parser; use embassy_executor::{Executor, Spawner}; use embassy_net::udp::UdpSocket; use embassy_net::{ConfigStrategy, Ipv4Address, Ipv4Cidr, PacketMetadata, Stack, StackResources}; -use embassy_util::Forever; use heapless::Vec; use log::*; use rand_core::{OsRng, RngCore}; +use static_cell::StaticCell; #[path = "../tuntap.rs"] mod tuntap; use crate::tuntap::TunTapDevice; -macro_rules! forever { +macro_rules! singleton { ($val:expr) => {{ type T = impl Sized; - static FOREVER: Forever = Forever::new(); - FOREVER.put_with(move || $val) + static STATIC_CELL: StaticCell = StaticCell::new(); + STATIC_CELL.init_with(move || $val) }}; } @@ -62,10 +62,10 @@ async fn main_task(spawner: Spawner) { let seed = u64::from_le_bytes(seed); // Init network stack - let stack = &*forever!(Stack::new( + let stack = &*singleton!(Stack::new( device, config, - forever!(StackResources::<1, 2, 8>::new()), + singleton!(StackResources::<1, 2, 8>::new()), seed )); @@ -93,7 +93,7 @@ async fn main_task(spawner: Spawner) { } } -static EXECUTOR: Forever = Forever::new(); +static EXECUTOR: StaticCell = StaticCell::new(); fn main() { env_logger::builder() @@ -102,7 +102,7 @@ fn main() { .format_timestamp_nanos() .init(); - let executor = EXECUTOR.put(Executor::new()); + let executor = EXECUTOR.init(Executor::new()); executor.run(|spawner| { spawner.spawn(main_task(spawner)).unwrap(); }); diff --git a/examples/std/src/bin/serial.rs b/examples/std/src/bin/serial.rs index 35cba4ce..85ee54f7 100644 --- a/examples/std/src/bin/serial.rs +++ b/examples/std/src/bin/serial.rs @@ -5,10 +5,10 @@ mod serial_port; use async_io::Async; use embassy_executor::Executor; -use embassy_util::Forever; use embedded_io::asynch::Read; use log::*; use nix::sys::termios; +use static_cell::StaticCell; use self::serial_port::SerialPort; @@ -40,7 +40,7 @@ async fn run() { } } -static EXECUTOR: Forever = Forever::new(); +static EXECUTOR: StaticCell = StaticCell::new(); fn main() { env_logger::builder() @@ -49,7 +49,7 @@ fn main() { .format_timestamp_nanos() .init(); - let executor = EXECUTOR.put(Executor::new()); + let executor = EXECUTOR.init(Executor::new()); executor.run(|spawner| { spawner.spawn(run()).unwrap(); }); diff --git a/examples/stm32f3/Cargo.toml b/examples/stm32f3/Cargo.toml index b5ea28bb..4e6b0ea1 100644 --- a/examples/stm32f3/Cargo.toml +++ b/examples/stm32f3/Cargo.toml @@ -23,3 +23,4 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa heapless = { version = "0.7.5", default-features = false } nb = "1.0.0" embedded-storage = "0.3.0" +static_cell = "1.0" diff --git a/examples/stm32f3/src/bin/multiprio.rs b/examples/stm32f3/src/bin/multiprio.rs index e96c3124..9e8228a4 100644 --- a/examples/stm32f3/src/bin/multiprio.rs +++ b/examples/stm32f3/src/bin/multiprio.rs @@ -63,7 +63,7 @@ use embassy_stm32::executor::{Executor, InterruptExecutor}; use embassy_stm32::interrupt; use embassy_stm32::interrupt::InterruptExt; use embassy_time::{Duration, Instant, Timer}; -use embassy_util::Forever; +use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::task] @@ -108,9 +108,9 @@ async fn run_low() { } } -static EXECUTOR_HIGH: Forever> = Forever::new(); -static EXECUTOR_MED: Forever> = Forever::new(); -static EXECUTOR_LOW: Forever = Forever::new(); +static EXECUTOR_HIGH: StaticCell> = StaticCell::new(); +static EXECUTOR_MED: StaticCell> = StaticCell::new(); +static EXECUTOR_LOW: StaticCell = StaticCell::new(); #[entry] fn main() -> ! { @@ -121,19 +121,19 @@ fn main() -> ! { // High-priority executor: SWI1_EGU1, priority level 6 let irq = interrupt::take!(UART4); irq.set_priority(interrupt::Priority::P6); - let executor = EXECUTOR_HIGH.put(InterruptExecutor::new(irq)); + let executor = EXECUTOR_HIGH.init(InterruptExecutor::new(irq)); let spawner = executor.start(); unwrap!(spawner.spawn(run_high())); // Medium-priority executor: SWI0_EGU0, priority level 7 let irq = interrupt::take!(UART5); irq.set_priority(interrupt::Priority::P7); - let executor = EXECUTOR_MED.put(InterruptExecutor::new(irq)); + let executor = EXECUTOR_MED.init(InterruptExecutor::new(irq)); let spawner = executor.start(); unwrap!(spawner.spawn(run_med())); // Low priority executor: runs in thread mode, using WFE/SEV - let executor = EXECUTOR_LOW.put(Executor::new()); + let executor = EXECUTOR_LOW.init(Executor::new()); executor.run(|spawner| { unwrap!(spawner.spawn(run_low())); }); diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml index 04a217af..f93a1d0f 100644 --- a/examples/stm32f4/Cargo.toml +++ b/examples/stm32f4/Cargo.toml @@ -23,6 +23,7 @@ heapless = { version = "0.7.5", default-features = false } nb = "1.0.0" embedded-storage = "0.3.0" micromath = "2.0.0" +static_cell = "1.0" usb-device = "0.2" usbd-serial = "0.1.1" diff --git a/examples/stm32f4/src/bin/multiprio.rs b/examples/stm32f4/src/bin/multiprio.rs index e96c3124..9e8228a4 100644 --- a/examples/stm32f4/src/bin/multiprio.rs +++ b/examples/stm32f4/src/bin/multiprio.rs @@ -63,7 +63,7 @@ use embassy_stm32::executor::{Executor, InterruptExecutor}; use embassy_stm32::interrupt; use embassy_stm32::interrupt::InterruptExt; use embassy_time::{Duration, Instant, Timer}; -use embassy_util::Forever; +use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::task] @@ -108,9 +108,9 @@ async fn run_low() { } } -static EXECUTOR_HIGH: Forever> = Forever::new(); -static EXECUTOR_MED: Forever> = Forever::new(); -static EXECUTOR_LOW: Forever = Forever::new(); +static EXECUTOR_HIGH: StaticCell> = StaticCell::new(); +static EXECUTOR_MED: StaticCell> = StaticCell::new(); +static EXECUTOR_LOW: StaticCell = StaticCell::new(); #[entry] fn main() -> ! { @@ -121,19 +121,19 @@ fn main() -> ! { // High-priority executor: SWI1_EGU1, priority level 6 let irq = interrupt::take!(UART4); irq.set_priority(interrupt::Priority::P6); - let executor = EXECUTOR_HIGH.put(InterruptExecutor::new(irq)); + let executor = EXECUTOR_HIGH.init(InterruptExecutor::new(irq)); let spawner = executor.start(); unwrap!(spawner.spawn(run_high())); // Medium-priority executor: SWI0_EGU0, priority level 7 let irq = interrupt::take!(UART5); irq.set_priority(interrupt::Priority::P7); - let executor = EXECUTOR_MED.put(InterruptExecutor::new(irq)); + let executor = EXECUTOR_MED.init(InterruptExecutor::new(irq)); let spawner = executor.start(); unwrap!(spawner.spawn(run_med())); // Low priority executor: runs in thread mode, using WFE/SEV - let executor = EXECUTOR_LOW.put(Executor::new()); + let executor = EXECUTOR_LOW.init(Executor::new()); executor.run(|spawner| { unwrap!(spawner.spawn(run_low())); }); diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml index 29d6da4d..e286d231 100644 --- a/examples/stm32f7/Cargo.toml +++ b/examples/stm32f7/Cargo.toml @@ -24,3 +24,4 @@ nb = "1.0.0" rand_core = "0.6.3" critical-section = "1.1" embedded-storage = "0.3.0" +static_cell = "1.0" diff --git a/examples/stm32f7/src/bin/eth.rs b/examples/stm32f7/src/bin/eth.rs index bdffabcb..5202edf6 100644 --- a/examples/stm32f7/src/bin/eth.rs +++ b/examples/stm32f7/src/bin/eth.rs @@ -13,16 +13,16 @@ use embassy_stm32::rng::Rng; use embassy_stm32::time::mhz; use embassy_stm32::{interrupt, Config}; use embassy_time::{Duration, Timer}; -use embassy_util::Forever; use embedded_io::asynch::Write; use rand_core::RngCore; +use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; -macro_rules! forever { +macro_rules! singleton { ($val:expr) => {{ type T = impl Sized; - static FOREVER: Forever = Forever::new(); - FOREVER.put_with(move || $val) + static STATIC_CELL: StaticCell = StaticCell::new(); + STATIC_CELL.init_with(move || $val) }}; } @@ -52,7 +52,7 @@ async fn main(spawner: Spawner) -> ! { let device = unsafe { Ethernet::new( - forever!(State::new()), + singleton!(State::new()), p.ETH, eth_int, p.PA1, @@ -78,10 +78,10 @@ async fn main(spawner: Spawner) -> ! { //}); // Init network stack - let stack = &*forever!(Stack::new( + let stack = &*singleton!(Stack::new( device, config, - forever!(StackResources::<1, 2, 8>::new()), + singleton!(StackResources::<1, 2, 8>::new()), seed )); diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml index a416796e..fc5f74f9 100644 --- a/examples/stm32h7/Cargo.toml +++ b/examples/stm32h7/Cargo.toml @@ -28,6 +28,7 @@ critical-section = "1.1" micromath = "2.0.0" stm32-fmc = "0.2.4" embedded-storage = "0.3.0" +static_cell = "1.0" # cargo build/run [profile.dev] diff --git a/examples/stm32h7/src/bin/eth.rs b/examples/stm32h7/src/bin/eth.rs index 83210bcb..4ccc0b5e 100644 --- a/examples/stm32h7/src/bin/eth.rs +++ b/examples/stm32h7/src/bin/eth.rs @@ -13,16 +13,16 @@ use embassy_stm32::rng::Rng; use embassy_stm32::time::mhz; use embassy_stm32::{interrupt, Config}; use embassy_time::{Duration, Timer}; -use embassy_util::Forever; use embedded_io::asynch::Write; use rand_core::RngCore; +use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; -macro_rules! forever { +macro_rules! singleton { ($val:expr) => {{ type T = impl Sized; - static FOREVER: Forever = Forever::new(); - FOREVER.put_with(move || $val) + static STATIC_CELL: StaticCell = StaticCell::new(); + STATIC_CELL.init_with(move || $val) }}; } @@ -53,7 +53,7 @@ async fn main(spawner: Spawner) -> ! { let device = unsafe { Ethernet::new( - forever!(State::new()), + singleton!(State::new()), p.ETH, eth_int, p.PA1, @@ -79,10 +79,10 @@ async fn main(spawner: Spawner) -> ! { //}); // Init network stack - let stack = &*forever!(Stack::new( + let stack = &*singleton!(Stack::new( device, config, - forever!(StackResources::<1, 2, 8>::new()), + singleton!(StackResources::<1, 2, 8>::new()), seed )); diff --git a/examples/stm32h7/src/bin/eth_client.rs b/examples/stm32h7/src/bin/eth_client.rs index 99946f50..64fd8414 100644 --- a/examples/stm32h7/src/bin/eth_client.rs +++ b/examples/stm32h7/src/bin/eth_client.rs @@ -13,17 +13,17 @@ use embassy_stm32::rng::Rng; use embassy_stm32::time::mhz; use embassy_stm32::{interrupt, Config}; use embassy_time::{Duration, Timer}; -use embassy_util::Forever; use embedded_io::asynch::Write; use embedded_nal_async::{Ipv4Addr, SocketAddr, SocketAddrV4, TcpConnect}; use rand_core::RngCore; +use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; -macro_rules! forever { +macro_rules! singleton { ($val:expr) => {{ type T = impl Sized; - static FOREVER: Forever = Forever::new(); - FOREVER.put_with(move || $val) + static STATIC_CELL: StaticCell = StaticCell::new(); + STATIC_CELL.init_with(move || $val) }}; } @@ -54,7 +54,7 @@ async fn main(spawner: Spawner) -> ! { let device = unsafe { Ethernet::new( - forever!(State::new()), + singleton!(State::new()), p.ETH, eth_int, p.PA1, @@ -80,10 +80,10 @@ async fn main(spawner: Spawner) -> ! { //}); // Init network stack - let stack = &*forever!(Stack::new( + let stack = &*singleton!(Stack::new( device, config, - forever!(StackResources::<1, 2, 8>::new()), + singleton!(StackResources::<1, 2, 8>::new()), seed )); diff --git a/examples/stm32h7/src/bin/spi.rs b/examples/stm32h7/src/bin/spi.rs index c28f937a..1f407f00 100644 --- a/examples/stm32h7/src/bin/spi.rs +++ b/examples/stm32h7/src/bin/spi.rs @@ -12,8 +12,8 @@ use embassy_stm32::dma::NoDma; use embassy_stm32::peripherals::SPI3; use embassy_stm32::time::mhz; use embassy_stm32::{spi, Config}; -use embassy_util::Forever; use heapless::String; +use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::task] @@ -31,7 +31,7 @@ async fn main_task(mut spi: spi::Spi<'static, SPI3, NoDma, NoDma>) { } } -static EXECUTOR: Forever = Forever::new(); +static EXECUTOR: StaticCell = StaticCell::new(); #[entry] fn main() -> ! { @@ -54,7 +54,7 @@ fn main() -> ! { spi::Config::default(), ); - let executor = EXECUTOR.put(Executor::new()); + let executor = EXECUTOR.init(Executor::new()); executor.run(|spawner| { unwrap!(spawner.spawn(main_task(spi))); diff --git a/examples/stm32h7/src/bin/spi_dma.rs b/examples/stm32h7/src/bin/spi_dma.rs index 6c78c194..53004fc9 100644 --- a/examples/stm32h7/src/bin/spi_dma.rs +++ b/examples/stm32h7/src/bin/spi_dma.rs @@ -11,8 +11,8 @@ use embassy_executor::Executor; use embassy_stm32::peripherals::{DMA1_CH3, DMA1_CH4, SPI3}; use embassy_stm32::time::mhz; use embassy_stm32::{spi, Config}; -use embassy_util::Forever; use heapless::String; +use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::task] @@ -27,7 +27,7 @@ async fn main_task(mut spi: spi::Spi<'static, SPI3, DMA1_CH3, DMA1_CH4>) { } } -static EXECUTOR: Forever = Forever::new(); +static EXECUTOR: StaticCell = StaticCell::new(); #[entry] fn main() -> ! { @@ -50,7 +50,7 @@ fn main() -> ! { spi::Config::default(), ); - let executor = EXECUTOR.put(Executor::new()); + let executor = EXECUTOR.init(Executor::new()); executor.run(|spawner| { unwrap!(spawner.spawn(main_task(spi))); diff --git a/examples/stm32h7/src/bin/usart.rs b/examples/stm32h7/src/bin/usart.rs index 1384d54c..87c2b125 100644 --- a/examples/stm32h7/src/bin/usart.rs +++ b/examples/stm32h7/src/bin/usart.rs @@ -7,7 +7,7 @@ use defmt::*; use embassy_executor::Executor; use embassy_stm32::dma::NoDma; use embassy_stm32::usart::{Config, Uart}; -use embassy_util::Forever; +use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::task] @@ -27,13 +27,13 @@ async fn main_task() { } } -static EXECUTOR: Forever = Forever::new(); +static EXECUTOR: StaticCell = StaticCell::new(); #[entry] fn main() -> ! { info!("Hello World!"); - let executor = EXECUTOR.put(Executor::new()); + let executor = EXECUTOR.init(Executor::new()); executor.run(|spawner| { unwrap!(spawner.spawn(main_task())); diff --git a/examples/stm32h7/src/bin/usart_dma.rs b/examples/stm32h7/src/bin/usart_dma.rs index f8d58bb8..3adffcbe 100644 --- a/examples/stm32h7/src/bin/usart_dma.rs +++ b/examples/stm32h7/src/bin/usart_dma.rs @@ -9,8 +9,8 @@ use defmt::*; use embassy_executor::Executor; use embassy_stm32::dma::NoDma; use embassy_stm32::usart::{Config, Uart}; -use embassy_util::Forever; use heapless::String; +use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; #[embassy_executor::task] @@ -30,13 +30,13 @@ async fn main_task() { } } -static EXECUTOR: Forever = Forever::new(); +static EXECUTOR: StaticCell = StaticCell::new(); #[entry] fn main() -> ! { info!("Hello World!"); - let executor = EXECUTOR.put(Executor::new()); + let executor = EXECUTOR.init(Executor::new()); executor.run(|spawner| { unwrap!(spawner.spawn(main_task())); diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml index fdb716d1..72365a64 100644 --- a/examples/stm32l0/Cargo.toml +++ b/examples/stm32l0/Cargo.toml @@ -29,3 +29,4 @@ panic-probe = { version = "0.3", features = ["print-defmt"] } futures = { version = "0.3.17", default-features = false, features = ["async-await"] } heapless = { version = "0.7.5", default-features = false } embedded-hal = "0.2.6" +static_cell = "1.0" diff --git a/examples/stm32l0/src/bin/raw_spawn.rs b/examples/stm32l0/src/bin/raw_spawn.rs index bd87e62a..edc17304 100644 --- a/examples/stm32l0/src/bin/raw_spawn.rs +++ b/examples/stm32l0/src/bin/raw_spawn.rs @@ -8,7 +8,7 @@ use defmt::*; use embassy_executor::raw::TaskStorage; use embassy_executor::Executor; use embassy_time::{Duration, Timer}; -use embassy_util::Forever; +use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; async fn run1() { @@ -25,14 +25,14 @@ async fn run2() { } } -static EXECUTOR: Forever = Forever::new(); +static EXECUTOR: StaticCell = StaticCell::new(); #[entry] fn main() -> ! { info!("Hello World!"); let _p = embassy_stm32::init(Default::default()); - let executor = EXECUTOR.put(Executor::new()); + let executor = EXECUTOR.init(Executor::new()); let run1_task = TaskStorage::new(); let run2_task = TaskStorage::new(); diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml index 4d96d31f..d8e78088 100644 --- a/examples/stm32l5/Cargo.toml +++ b/examples/stm32l5/Cargo.toml @@ -28,3 +28,4 @@ futures = { version = "0.3.17", default-features = false, features = ["async-awa heapless = { version = "0.7.5", default-features = false } rand_core = { version = "0.6.3", default-features = false } embedded-io = { version = "0.3.0", features = ["async"] } +static_cell = "1.0" diff --git a/examples/stm32l5/src/bin/usb_ethernet.rs b/examples/stm32l5/src/bin/usb_ethernet.rs index 7c53d03c..95919551 100644 --- a/examples/stm32l5/src/bin/usb_ethernet.rs +++ b/examples/stm32l5/src/bin/usb_ethernet.rs @@ -19,18 +19,18 @@ use embassy_usb::{Builder, UsbDevice}; use embassy_usb_ncm::{CdcNcmClass, Receiver, Sender, State}; use embassy_util::blocking_mutex::raw::ThreadModeRawMutex; use embassy_util::channel::mpmc::Channel; -use embassy_util::Forever; use embedded_io::asynch::{Read, Write}; use rand_core::RngCore; +use static_cell::StaticCell; use {defmt_rtt as _, panic_probe as _}; type MyDriver = Driver<'static, embassy_stm32::peripherals::USB>; -macro_rules! forever { +macro_rules! singleton { ($val:expr) => {{ type T = impl Sized; - static FOREVER: Forever = Forever::new(); - FOREVER.put_with(move || $val) + static STATIC_CELL: StaticCell = StaticCell::new(); + STATIC_CELL.init_with(move || $val) }}; } @@ -115,7 +115,7 @@ async fn main(spawner: Spawner) { control_buf: [u8; 128], serial_state: State<'static>, } - let res: &mut Resources = forever!(Resources { + let res: &mut Resources = singleton!(Resources { device_descriptor: [0; 256], config_descriptor: [0; 256], bos_descriptor: [0; 256], @@ -171,10 +171,10 @@ async fn main(spawner: Spawner) { // Init network stack let device = Device { mac_addr: our_mac_addr }; - let stack = &*forever!(Stack::new( + let stack = &*singleton!(Stack::new( device, config, - forever!(StackResources::<1, 2, 8>::new()), + singleton!(StackResources::<1, 2, 8>::new()), seed ));