diff options
50 files changed, 663 insertions, 518 deletions
diff --git a/docs/modules/ROOT/examples/basic/Cargo.toml b/docs/modules/ROOT/examples/basic/Cargo.toml index d9f8a285a..e3e446e63 100644 --- a/docs/modules/ROOT/examples/basic/Cargo.toml +++ b/docs/modules/ROOT/examples/basic/Cargo.toml | |||
| @@ -6,7 +6,7 @@ version = "0.1.0" | |||
| 6 | license = "MIT OR Apache-2.0" | 6 | license = "MIT OR Apache-2.0" |
| 7 | 7 | ||
| 8 | [dependencies] | 8 | [dependencies] |
| 9 | embassy-executor = { version = "0.1.0", path = "../../../../../embassy-executor", features = ["defmt", "nightly", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../../../../embassy-executor", features = ["defmt", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../../../../embassy-time", features = ["defmt", "nightly"] } | 10 | embassy-time = { version = "0.1.0", path = "../../../../../embassy-time", features = ["defmt", "nightly"] } |
| 11 | embassy-nrf = { version = "0.1.0", path = "../../../../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "nightly"] } | 11 | embassy-nrf = { version = "0.1.0", path = "../../../../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "nightly"] } |
| 12 | 12 | ||
diff --git a/docs/modules/ROOT/examples/layer-by-layer/blinky-async/Cargo.toml b/docs/modules/ROOT/examples/layer-by-layer/blinky-async/Cargo.toml index c9a963d4d..a11a7e0ba 100644 --- a/docs/modules/ROOT/examples/layer-by-layer/blinky-async/Cargo.toml +++ b/docs/modules/ROOT/examples/layer-by-layer/blinky-async/Cargo.toml | |||
| @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" | |||
| 8 | cortex-m = "0.7" | 8 | cortex-m = "0.7" |
| 9 | cortex-m-rt = "0.7" | 9 | cortex-m-rt = "0.7" |
| 10 | embassy-stm32 = { version = "0.1.0", features = ["stm32l475vg", "memory-x", "exti"], default-features = false } | 10 | embassy-stm32 = { version = "0.1.0", features = ["stm32l475vg", "memory-x", "exti"], default-features = false } |
| 11 | embassy-executor = { version = "0.1.0", default-features = false, features = ["nightly"] } | 11 | embassy-executor = { version = "0.1.0", default-features = false, features = ["nightly", "arch-cortex-m", "executor-thread"] } |
| 12 | 12 | ||
| 13 | defmt = "0.3.0" | 13 | defmt = "0.3.0" |
| 14 | defmt-rtt = "0.3.0" | 14 | defmt-rtt = "0.3.0" |
diff --git a/embassy-cortex-m/src/executor.rs b/embassy-cortex-m/src/executor.rs deleted file mode 100644 index 558539e73..000000000 --- a/embassy-cortex-m/src/executor.rs +++ /dev/null | |||
| @@ -1,116 +0,0 @@ | |||
| 1 | //! Executor specific to cortex-m devices. | ||
| 2 | |||
| 3 | use core::cell::UnsafeCell; | ||
| 4 | use core::mem::MaybeUninit; | ||
| 5 | |||
| 6 | use atomic_polyfill::{AtomicBool, Ordering}; | ||
| 7 | use cortex_m::interrupt::InterruptNumber; | ||
| 8 | use cortex_m::peripheral::NVIC; | ||
| 9 | pub use embassy_executor::*; | ||
| 10 | |||
| 11 | #[derive(Clone, Copy)] | ||
| 12 | struct N(u16); | ||
| 13 | unsafe impl cortex_m::interrupt::InterruptNumber for N { | ||
| 14 | fn number(self) -> u16 { | ||
| 15 | self.0 | ||
| 16 | } | ||
| 17 | } | ||
| 18 | |||
| 19 | fn pend_by_number(n: u16) { | ||
| 20 | cortex_m::peripheral::NVIC::pend(N(n)) | ||
| 21 | } | ||
| 22 | |||
| 23 | /// Interrupt mode executor. | ||
| 24 | /// | ||
| 25 | /// This executor runs tasks in interrupt mode. The interrupt handler is set up | ||
| 26 | /// to poll tasks, and when a task is woken the interrupt is pended from software. | ||
| 27 | /// | ||
| 28 | /// This allows running async tasks at a priority higher than thread mode. One | ||
| 29 | /// use case is to leave thread mode free for non-async tasks. Another use case is | ||
| 30 | /// to run multiple executors: one in thread mode for low priority tasks and another in | ||
| 31 | /// interrupt mode for higher priority tasks. Higher priority tasks will preempt lower | ||
| 32 | /// priority ones. | ||
| 33 | /// | ||
| 34 | /// It is even possible to run multiple interrupt mode executors at different priorities, | ||
| 35 | /// by assigning different priorities to the interrupts. For an example on how to do this, | ||
| 36 | /// See the 'multiprio' example for 'embassy-nrf'. | ||
| 37 | /// | ||
| 38 | /// To use it, you have to pick an interrupt that won't be used by the hardware. | ||
| 39 | /// Some chips reserve some interrupts for this purpose, sometimes named "software interrupts" (SWI). | ||
| 40 | /// If this is not the case, you may use an interrupt from any unused peripheral. | ||
| 41 | /// | ||
| 42 | /// It is somewhat more complex to use, it's recommended to use the thread-mode | ||
| 43 | /// [`Executor`] instead, if it works for your use case. | ||
| 44 | pub struct InterruptExecutor { | ||
| 45 | started: AtomicBool, | ||
| 46 | executor: UnsafeCell<MaybeUninit<raw::Executor>>, | ||
| 47 | } | ||
| 48 | |||
| 49 | unsafe impl Send for InterruptExecutor {} | ||
| 50 | unsafe impl Sync for InterruptExecutor {} | ||
| 51 | |||
| 52 | impl InterruptExecutor { | ||
| 53 | /// Create a new, not started `InterruptExecutor`. | ||
| 54 | #[inline] | ||
| 55 | pub const fn new() -> Self { | ||
| 56 | Self { | ||
| 57 | started: AtomicBool::new(false), | ||
| 58 | executor: UnsafeCell::new(MaybeUninit::uninit()), | ||
| 59 | } | ||
| 60 | } | ||
| 61 | |||
| 62 | /// Executor interrupt callback. | ||
| 63 | /// | ||
| 64 | /// # Safety | ||
| 65 | /// | ||
| 66 | /// You MUST call this from the interrupt handler, and from nowhere else. | ||
| 67 | pub unsafe fn on_interrupt(&'static self) { | ||
| 68 | let executor = unsafe { (&*self.executor.get()).assume_init_ref() }; | ||
| 69 | executor.poll(); | ||
| 70 | } | ||
| 71 | |||
| 72 | /// Start the executor. | ||
| 73 | /// | ||
| 74 | /// This initializes the executor, enables the interrupt, and returns. | ||
| 75 | /// The executor keeps running in the background through the interrupt. | ||
| 76 | /// | ||
| 77 | /// This returns a [`SendSpawner`] you can use to spawn tasks on it. A [`SendSpawner`] | ||
| 78 | /// is returned instead of a [`Spawner`](embassy_executor::Spawner) because the executor effectively runs in a | ||
| 79 | /// different "thread" (the interrupt), so spawning tasks on it is effectively | ||
| 80 | /// sending them. | ||
| 81 | /// | ||
| 82 | /// To obtain a [`Spawner`](embassy_executor::Spawner) for this executor, use [`Spawner::for_current_executor()`](embassy_executor::Spawner::for_current_executor()) from | ||
| 83 | /// a task running in it. | ||
| 84 | /// | ||
| 85 | /// # Interrupt requirements | ||
| 86 | /// | ||
| 87 | /// You must write the interrupt handler yourself, and make it call [`on_interrupt()`](Self::on_interrupt). | ||
| 88 | /// | ||
| 89 | /// This method already enables (unmasks) the interrupt, you must NOT do it yourself. | ||
| 90 | /// | ||
| 91 | /// You must set the interrupt priority before calling this method. You MUST NOT | ||
| 92 | /// do it after. | ||
| 93 | /// | ||
| 94 | pub fn start(&'static self, irq: impl InterruptNumber) -> SendSpawner { | ||
| 95 | if self | ||
| 96 | .started | ||
| 97 | .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) | ||
| 98 | .is_err() | ||
| 99 | { | ||
| 100 | panic!("InterruptExecutor::start() called multiple times on the same executor."); | ||
| 101 | } | ||
| 102 | |||
| 103 | unsafe { | ||
| 104 | (&mut *self.executor.get()).as_mut_ptr().write(raw::Executor::new( | ||
| 105 | |ctx| pend_by_number(ctx as u16), | ||
| 106 | irq.number() as *mut (), | ||
| 107 | )) | ||
| 108 | } | ||
| 109 | |||
| 110 | let executor = unsafe { (&*self.executor.get()).assume_init_ref() }; | ||
| 111 | |||
| 112 | unsafe { NVIC::unmask(irq) } | ||
| 113 | |||
| 114 | executor.spawner().make_send() | ||
| 115 | } | ||
| 116 | } | ||
diff --git a/embassy-cortex-m/src/lib.rs b/embassy-cortex-m/src/lib.rs index fba23367b..e4b713a06 100644 --- a/embassy-cortex-m/src/lib.rs +++ b/embassy-cortex-m/src/lib.rs | |||
| @@ -5,6 +5,6 @@ | |||
| 5 | // This mod MUST go first, so that the others see its macros. | 5 | // This mod MUST go first, so that the others see its macros. |
| 6 | pub(crate) mod fmt; | 6 | pub(crate) mod fmt; |
| 7 | 7 | ||
| 8 | pub mod executor; | 8 | pub use embassy_executor as executor; |
| 9 | pub mod interrupt; | 9 | pub mod interrupt; |
| 10 | pub mod peripheral; | 10 | pub mod peripheral; |
diff --git a/embassy-executor/Cargo.toml b/embassy-executor/Cargo.toml index 8ad3fd698..bb8a46c82 100644 --- a/embassy-executor/Cargo.toml +++ b/embassy-executor/Cargo.toml | |||
| @@ -31,9 +31,22 @@ flavors = [ | |||
| 31 | features = ["std", "nightly", "defmt"] | 31 | features = ["std", "nightly", "defmt"] |
| 32 | 32 | ||
| 33 | [features] | 33 | [features] |
| 34 | default = [] | 34 | |
| 35 | std = ["critical-section/std"] | 35 | # Architecture |
| 36 | wasm = ["dep:wasm-bindgen", "dep:js-sys"] | 36 | _arch = [] # some arch was picked |
| 37 | arch-std = ["_arch", "critical-section/std"] | ||
| 38 | arch-cortex-m = ["_arch", "dep:cortex-m"] | ||
| 39 | arch-xtensa = ["_arch"] | ||
| 40 | arch-riscv32 = ["_arch"] | ||
| 41 | arch-wasm = ["_arch", "dep:wasm-bindgen", "dep:js-sys"] | ||
| 42 | |||
| 43 | # Enable creating a `Pender` from an arbitrary function pointer callback. | ||
| 44 | pender-callback = [] | ||
| 45 | |||
| 46 | # Enable the thread-mode executor (using WFE/SEV in Cortex-M, WFI in other embedded archs) | ||
| 47 | executor-thread = [] | ||
| 48 | # Enable the interrupt-mode executor (available in Cortex-M only) | ||
| 49 | executor-interrupt = [] | ||
| 37 | 50 | ||
| 38 | # Enable nightly-only features | 51 | # Enable nightly-only features |
| 39 | nightly = [] | 52 | nightly = [] |
| @@ -55,9 +68,11 @@ embassy-macros = { version = "0.1.0", path = "../embassy-macros" } | |||
| 55 | embassy-time = { version = "0.1.0", path = "../embassy-time", optional = true} | 68 | embassy-time = { version = "0.1.0", path = "../embassy-time", optional = true} |
| 56 | atomic-polyfill = "1.0.1" | 69 | atomic-polyfill = "1.0.1" |
| 57 | critical-section = "1.1" | 70 | critical-section = "1.1" |
| 58 | cfg-if = "1.0.0" | ||
| 59 | static_cell = "1.0" | 71 | static_cell = "1.0" |
| 60 | 72 | ||
| 61 | # WASM dependencies | 73 | # arch-cortex-m dependencies |
| 74 | cortex-m = { version = "0.7.6", optional = true } | ||
| 75 | |||
| 76 | # arch-wasm dependencies | ||
| 62 | wasm-bindgen = { version = "0.2.82", optional = true } | 77 | wasm-bindgen = { version = "0.2.82", optional = true } |
| 63 | js-sys = { version = "0.3", optional = true } | 78 | js-sys = { version = "0.3", optional = true } |
diff --git a/embassy-executor/src/arch/cortex_m.rs b/embassy-executor/src/arch/cortex_m.rs index 4b27a264e..d6a55c4c7 100644 --- a/embassy-executor/src/arch/cortex_m.rs +++ b/embassy-executor/src/arch/cortex_m.rs | |||
| @@ -1,59 +1,209 @@ | |||
| 1 | use core::arch::asm; | 1 | #[cfg(feature = "executor-thread")] |
| 2 | use core::marker::PhantomData; | 2 | pub use thread::*; |
| 3 | use core::ptr; | 3 | #[cfg(feature = "executor-thread")] |
| 4 | 4 | mod thread { | |
| 5 | use super::{raw, Spawner}; | 5 | use core::arch::asm; |
| 6 | 6 | use core::marker::PhantomData; | |
| 7 | /// Thread mode executor, using WFE/SEV. | 7 | |
| 8 | /// | 8 | #[cfg(feature = "nightly")] |
| 9 | /// This is the simplest and most common kind of executor. It runs on | 9 | pub use embassy_macros::main_cortex_m as main; |
| 10 | /// thread mode (at the lowest priority level), and uses the `WFE` ARM instruction | 10 | |
| 11 | /// to sleep when it has no more work to do. When a task is woken, a `SEV` instruction | 11 | use crate::raw::{Pender, PenderInner}; |
| 12 | /// is executed, to make the `WFE` exit from sleep and poll the task. | 12 | use crate::{raw, Spawner}; |
| 13 | /// | 13 | |
| 14 | /// This executor allows for ultra low power consumption for chips where `WFE` | 14 | #[derive(Copy, Clone)] |
| 15 | /// triggers low-power sleep without extra steps. If your chip requires extra steps, | 15 | pub(crate) struct ThreadPender; |
| 16 | /// you may use [`raw::Executor`] directly to program custom behavior. | 16 | |
| 17 | pub struct Executor { | 17 | impl ThreadPender { |
| 18 | inner: raw::Executor, | 18 | pub(crate) fn pend(self) { |
| 19 | not_send: PhantomData<*mut ()>, | 19 | unsafe { core::arch::asm!("sev") } |
| 20 | } | ||
| 21 | } | ||
| 22 | |||
| 23 | /// Thread mode executor, using WFE/SEV. | ||
| 24 | /// | ||
| 25 | /// This is the simplest and most common kind of executor. It runs on | ||
| 26 | /// thread mode (at the lowest priority level), and uses the `WFE` ARM instruction | ||
| 27 | /// to sleep when it has no more work to do. When a task is woken, a `SEV` instruction | ||
| 28 | /// is executed, to make the `WFE` exit from sleep and poll the task. | ||
| 29 | /// | ||
| 30 | /// This executor allows for ultra low power consumption for chips where `WFE` | ||
| 31 | /// triggers low-power sleep without extra steps. If your chip requires extra steps, | ||
| 32 | /// you may use [`raw::Executor`] directly to program custom behavior. | ||
| 33 | pub struct Executor { | ||
| 34 | inner: raw::Executor, | ||
| 35 | not_send: PhantomData<*mut ()>, | ||
| 36 | } | ||
| 37 | |||
| 38 | impl Executor { | ||
| 39 | /// Create a new Executor. | ||
| 40 | pub fn new() -> Self { | ||
| 41 | Self { | ||
| 42 | inner: raw::Executor::new(Pender(PenderInner::Thread(ThreadPender))), | ||
| 43 | not_send: PhantomData, | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | /// Run the executor. | ||
| 48 | /// | ||
| 49 | /// The `init` closure is called with a [`Spawner`] that spawns tasks on | ||
| 50 | /// this executor. Use it to spawn the initial task(s). After `init` returns, | ||
| 51 | /// the executor starts running the tasks. | ||
| 52 | /// | ||
| 53 | /// To spawn more tasks later, you may keep copies of the [`Spawner`] (it is `Copy`), | ||
| 54 | /// for example by passing it as an argument to the initial tasks. | ||
| 55 | /// | ||
| 56 | /// This function requires `&'static mut self`. This means you have to store the | ||
| 57 | /// Executor instance in a place where it'll live forever and grants you mutable | ||
| 58 | /// access. There's a few ways to do this: | ||
| 59 | /// | ||
| 60 | /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe) | ||
| 61 | /// - a `static mut` (unsafe) | ||
| 62 | /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) | ||
| 63 | /// | ||
| 64 | /// This function never returns. | ||
| 65 | pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! { | ||
| 66 | init(self.inner.spawner()); | ||
| 67 | |||
| 68 | loop { | ||
| 69 | unsafe { | ||
| 70 | self.inner.poll(); | ||
| 71 | asm!("wfe"); | ||
| 72 | }; | ||
| 73 | } | ||
| 74 | } | ||
| 75 | } | ||
| 20 | } | 76 | } |
| 21 | 77 | ||
| 22 | impl Executor { | 78 | #[cfg(feature = "executor-interrupt")] |
| 23 | /// Create a new Executor. | 79 | pub use interrupt::*; |
| 24 | pub fn new() -> Self { | 80 | #[cfg(feature = "executor-interrupt")] |
| 25 | Self { | 81 | mod interrupt { |
| 26 | inner: raw::Executor::new(|_| unsafe { asm!("sev") }, ptr::null_mut()), | 82 | use core::cell::UnsafeCell; |
| 27 | not_send: PhantomData, | 83 | use core::mem::MaybeUninit; |
| 84 | |||
| 85 | use atomic_polyfill::{AtomicBool, Ordering}; | ||
| 86 | use cortex_m::interrupt::InterruptNumber; | ||
| 87 | use cortex_m::peripheral::NVIC; | ||
| 88 | |||
| 89 | use crate::raw::{self, Pender, PenderInner}; | ||
| 90 | |||
| 91 | #[derive(Clone, Copy)] | ||
| 92 | pub(crate) struct InterruptPender(u16); | ||
| 93 | |||
| 94 | impl InterruptPender { | ||
| 95 | pub(crate) fn pend(self) { | ||
| 96 | // STIR is faster, but is only available in v7 and higher. | ||
| 97 | #[cfg(not(armv6m))] | ||
| 98 | { | ||
| 99 | let mut nvic: cortex_m::peripheral::NVIC = unsafe { core::mem::transmute(()) }; | ||
| 100 | nvic.request(self); | ||
| 101 | } | ||
| 102 | |||
| 103 | #[cfg(armv6m)] | ||
| 104 | cortex_m::peripheral::NVIC::pend(self); | ||
| 28 | } | 105 | } |
| 29 | } | 106 | } |
| 30 | 107 | ||
| 31 | /// Run the executor. | 108 | unsafe impl cortex_m::interrupt::InterruptNumber for InterruptPender { |
| 109 | fn number(self) -> u16 { | ||
| 110 | self.0 | ||
| 111 | } | ||
| 112 | } | ||
| 113 | |||
| 114 | /// Interrupt mode executor. | ||
| 32 | /// | 115 | /// |
| 33 | /// The `init` closure is called with a [`Spawner`] that spawns tasks on | 116 | /// This executor runs tasks in interrupt mode. The interrupt handler is set up |
| 34 | /// this executor. Use it to spawn the initial task(s). After `init` returns, | 117 | /// to poll tasks, and when a task is woken the interrupt is pended from software. |
| 35 | /// the executor starts running the tasks. | ||
| 36 | /// | 118 | /// |
| 37 | /// To spawn more tasks later, you may keep copies of the [`Spawner`] (it is `Copy`), | 119 | /// This allows running async tasks at a priority higher than thread mode. One |
| 38 | /// for example by passing it as an argument to the initial tasks. | 120 | /// use case is to leave thread mode free for non-async tasks. Another use case is |
| 121 | /// to run multiple executors: one in thread mode for low priority tasks and another in | ||
| 122 | /// interrupt mode for higher priority tasks. Higher priority tasks will preempt lower | ||
| 123 | /// priority ones. | ||
| 39 | /// | 124 | /// |
| 40 | /// This function requires `&'static mut self`. This means you have to store the | 125 | /// It is even possible to run multiple interrupt mode executors at different priorities, |
| 41 | /// Executor instance in a place where it'll live forever and grants you mutable | 126 | /// by assigning different priorities to the interrupts. For an example on how to do this, |
| 42 | /// access. There's a few ways to do this: | 127 | /// See the 'multiprio' example for 'embassy-nrf'. |
| 43 | /// | 128 | /// |
| 44 | /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe) | 129 | /// To use it, you have to pick an interrupt that won't be used by the hardware. |
| 45 | /// - a `static mut` (unsafe) | 130 | /// Some chips reserve some interrupts for this purpose, sometimes named "software interrupts" (SWI). |
| 46 | /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) | 131 | /// If this is not the case, you may use an interrupt from any unused peripheral. |
| 47 | /// | 132 | /// |
| 48 | /// This function never returns. | 133 | /// It is somewhat more complex to use, it's recommended to use the thread-mode |
| 49 | pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! { | 134 | /// [`Executor`] instead, if it works for your use case. |
| 50 | init(self.inner.spawner()); | 135 | pub struct InterruptExecutor { |
| 136 | started: AtomicBool, | ||
| 137 | executor: UnsafeCell<MaybeUninit<raw::Executor>>, | ||
| 138 | } | ||
| 139 | |||
| 140 | unsafe impl Send for InterruptExecutor {} | ||
| 141 | unsafe impl Sync for InterruptExecutor {} | ||
| 142 | |||
| 143 | impl InterruptExecutor { | ||
| 144 | /// Create a new, not started `InterruptExecutor`. | ||
| 145 | #[inline] | ||
| 146 | pub const fn new() -> Self { | ||
| 147 | Self { | ||
| 148 | started: AtomicBool::new(false), | ||
| 149 | executor: UnsafeCell::new(MaybeUninit::uninit()), | ||
| 150 | } | ||
| 151 | } | ||
| 152 | |||
| 153 | /// Executor interrupt callback. | ||
| 154 | /// | ||
| 155 | /// # Safety | ||
| 156 | /// | ||
| 157 | /// You MUST call this from the interrupt handler, and from nowhere else. | ||
| 158 | pub unsafe fn on_interrupt(&'static self) { | ||
| 159 | let executor = unsafe { (&*self.executor.get()).assume_init_ref() }; | ||
| 160 | executor.poll(); | ||
| 161 | } | ||
| 162 | |||
| 163 | /// Start the executor. | ||
| 164 | /// | ||
| 165 | /// This initializes the executor, enables the interrupt, and returns. | ||
| 166 | /// The executor keeps running in the background through the interrupt. | ||
| 167 | /// | ||
| 168 | /// This returns a [`SendSpawner`] you can use to spawn tasks on it. A [`SendSpawner`] | ||
| 169 | /// is returned instead of a [`Spawner`](embassy_executor::Spawner) because the executor effectively runs in a | ||
| 170 | /// different "thread" (the interrupt), so spawning tasks on it is effectively | ||
| 171 | /// sending them. | ||
| 172 | /// | ||
| 173 | /// To obtain a [`Spawner`](embassy_executor::Spawner) for this executor, use [`Spawner::for_current_executor()`](embassy_executor::Spawner::for_current_executor()) from | ||
| 174 | /// a task running in it. | ||
| 175 | /// | ||
| 176 | /// # Interrupt requirements | ||
| 177 | /// | ||
| 178 | /// You must write the interrupt handler yourself, and make it call [`on_interrupt()`](Self::on_interrupt). | ||
| 179 | /// | ||
| 180 | /// This method already enables (unmasks) the interrupt, you must NOT do it yourself. | ||
| 181 | /// | ||
| 182 | /// You must set the interrupt priority before calling this method. You MUST NOT | ||
| 183 | /// do it after. | ||
| 184 | /// | ||
| 185 | pub fn start(&'static self, irq: impl InterruptNumber) -> crate::SendSpawner { | ||
| 186 | if self | ||
| 187 | .started | ||
| 188 | .compare_exchange(false, true, Ordering::Acquire, Ordering::Relaxed) | ||
| 189 | .is_err() | ||
| 190 | { | ||
| 191 | panic!("InterruptExecutor::start() called multiple times on the same executor."); | ||
| 192 | } | ||
| 51 | 193 | ||
| 52 | loop { | ||
| 53 | unsafe { | 194 | unsafe { |
| 54 | self.inner.poll(); | 195 | (&mut *self.executor.get()) |
| 55 | asm!("wfe"); | 196 | .as_mut_ptr() |
| 56 | }; | 197 | .write(raw::Executor::new(Pender(PenderInner::Interrupt(InterruptPender( |
| 198 | irq.number(), | ||
| 199 | ))))) | ||
| 200 | } | ||
| 201 | |||
| 202 | let executor = unsafe { (&*self.executor.get()).assume_init_ref() }; | ||
| 203 | |||
| 204 | unsafe { NVIC::unmask(irq) } | ||
| 205 | |||
| 206 | executor.spawner().make_send() | ||
| 57 | } | 207 | } |
| 58 | } | 208 | } |
| 59 | } | 209 | } |
diff --git a/embassy-executor/src/arch/riscv32.rs b/embassy-executor/src/arch/riscv32.rs index e97a56cda..f66daeae4 100644 --- a/embassy-executor/src/arch/riscv32.rs +++ b/embassy-executor/src/arch/riscv32.rs | |||
| @@ -1,72 +1,83 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | #[cfg(feature = "executor-interrupt")] |
| 2 | use core::ptr; | 2 | compile_error!("`executor-interrupt` is not supported with `arch-riscv32`."); |
| 3 | use core::sync::atomic::{AtomicBool, Ordering}; | ||
| 4 | 3 | ||
| 5 | use super::{raw, Spawner}; | 4 | #[cfg(feature = "executor-thread")] |
| 5 | pub use thread::*; | ||
| 6 | #[cfg(feature = "executor-thread")] | ||
| 7 | mod thread { | ||
| 8 | use core::marker::PhantomData; | ||
| 9 | use core::sync::atomic::{AtomicBool, Ordering}; | ||
| 6 | 10 | ||
| 7 | /// global atomic used to keep track of whether there is work to do since sev() is not available on RISCV | 11 | use crate::raw::{Pender, PenderInner}; |
| 8 | /// | 12 | use crate::{raw, Spawner}; |
| 9 | static SIGNAL_WORK_THREAD_MODE: AtomicBool = AtomicBool::new(false); | ||
| 10 | 13 | ||
| 11 | /// RISCV32 Executor | 14 | #[derive(Copy, Clone)] |
| 12 | pub struct Executor { | 15 | pub(crate) struct ThreadPender; |
| 13 | inner: raw::Executor, | ||
| 14 | not_send: PhantomData<*mut ()>, | ||
| 15 | } | ||
| 16 | 16 | ||
| 17 | impl Executor { | 17 | impl ThreadPender { |
| 18 | /// Create a new Executor. | 18 | #[allow(unused)] |
| 19 | pub fn new() -> Self { | 19 | pub(crate) fn pend(self) { |
| 20 | Self { | 20 | SIGNAL_WORK_THREAD_MODE.store(true, core::sync::atomic::Ordering::SeqCst); |
| 21 | // use Signal_Work_Thread_Mode as substitute for local interrupt register | ||
| 22 | inner: raw::Executor::new( | ||
| 23 | |_| { | ||
| 24 | SIGNAL_WORK_THREAD_MODE.store(true, Ordering::SeqCst); | ||
| 25 | }, | ||
| 26 | ptr::null_mut(), | ||
| 27 | ), | ||
| 28 | not_send: PhantomData, | ||
| 29 | } | 21 | } |
| 30 | } | 22 | } |
| 31 | 23 | ||
| 32 | /// Run the executor. | 24 | /// global atomic used to keep track of whether there is work to do since sev() is not available on RISCV |
| 33 | /// | 25 | static SIGNAL_WORK_THREAD_MODE: AtomicBool = AtomicBool::new(false); |
| 34 | /// The `init` closure is called with a [`Spawner`] that spawns tasks on | 26 | |
| 35 | /// this executor. Use it to spawn the initial task(s). After `init` returns, | 27 | /// RISCV32 Executor |
| 36 | /// the executor starts running the tasks. | 28 | pub struct Executor { |
| 37 | /// | 29 | inner: raw::Executor, |
| 38 | /// To spawn more tasks later, you may keep copies of the [`Spawner`] (it is `Copy`), | 30 | not_send: PhantomData<*mut ()>, |
| 39 | /// for example by passing it as an argument to the initial tasks. | 31 | } |
| 40 | /// | 32 | |
| 41 | /// This function requires `&'static mut self`. This means you have to store the | 33 | impl Executor { |
| 42 | /// Executor instance in a place where it'll live forever and grants you mutable | 34 | /// Create a new Executor. |
| 43 | /// access. There's a few ways to do this: | 35 | pub fn new() -> Self { |
| 44 | /// | 36 | Self { |
| 45 | /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe) | 37 | inner: raw::Executor::new(Pender(PenderInner::Thread(ThreadPender))), |
| 46 | /// - a `static mut` (unsafe) | 38 | not_send: PhantomData, |
| 47 | /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) | 39 | } |
| 48 | /// | 40 | } |
| 49 | /// This function never returns. | 41 | |
| 50 | pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! { | 42 | /// Run the executor. |
| 51 | init(self.inner.spawner()); | 43 | /// |
| 44 | /// The `init` closure is called with a [`Spawner`] that spawns tasks on | ||
| 45 | /// this executor. Use it to spawn the initial task(s). After `init` returns, | ||
| 46 | /// the executor starts running the tasks. | ||
| 47 | /// | ||
| 48 | /// To spawn more tasks later, you may keep copies of the [`Spawner`] (it is `Copy`), | ||
| 49 | /// for example by passing it as an argument to the initial tasks. | ||
| 50 | /// | ||
| 51 | /// This function requires `&'static mut self`. This means you have to store the | ||
| 52 | /// Executor instance in a place where it'll live forever and grants you mutable | ||
| 53 | /// access. There's a few ways to do this: | ||
| 54 | /// | ||
| 55 | /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe) | ||
| 56 | /// - a `static mut` (unsafe) | ||
| 57 | /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) | ||
| 58 | /// | ||
| 59 | /// This function never returns. | ||
| 60 | pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! { | ||
| 61 | init(self.inner.spawner()); | ||
| 52 | 62 | ||
| 53 | loop { | 63 | loop { |
| 54 | unsafe { | 64 | unsafe { |
| 55 | self.inner.poll(); | 65 | self.inner.poll(); |
| 56 | // we do not care about race conditions between the load and store operations, interrupts | 66 | // we do not care about race conditions between the load and store operations, interrupts |
| 57 | //will only set this value to true. | 67 | //will only set this value to true. |
| 58 | critical_section::with(|_| { | 68 | critical_section::with(|_| { |
| 59 | // if there is work to do, loop back to polling | 69 | // if there is work to do, loop back to polling |
| 60 | // TODO can we relax this? | 70 | // TODO can we relax this? |
| 61 | if SIGNAL_WORK_THREAD_MODE.load(Ordering::SeqCst) { | 71 | if SIGNAL_WORK_THREAD_MODE.load(Ordering::SeqCst) { |
| 62 | SIGNAL_WORK_THREAD_MODE.store(false, Ordering::SeqCst); | 72 | SIGNAL_WORK_THREAD_MODE.store(false, Ordering::SeqCst); |
| 63 | } | 73 | } |
| 64 | // if not, wait for interrupt | 74 | // if not, wait for interrupt |
| 65 | else { | 75 | else { |
| 66 | core::arch::asm!("wfi"); | 76 | core::arch::asm!("wfi"); |
| 67 | } | 77 | } |
| 68 | }); | 78 | }); |
| 69 | // if an interrupt occurred while waiting, it will be serviced here | 79 | // if an interrupt occurred while waiting, it will be serviced here |
| 80 | } | ||
| 70 | } | 81 | } |
| 71 | } | 82 | } |
| 72 | } | 83 | } |
diff --git a/embassy-executor/src/arch/std.rs b/embassy-executor/src/arch/std.rs index 701f0eb18..4e4a178f0 100644 --- a/embassy-executor/src/arch/std.rs +++ b/embassy-executor/src/arch/std.rs | |||
| @@ -1,84 +1,100 @@ | |||
| 1 | use std::marker::PhantomData; | 1 | #[cfg(feature = "executor-interrupt")] |
| 2 | use std::sync::{Condvar, Mutex}; | 2 | compile_error!("`executor-interrupt` is not supported with `arch-std`."); |
| 3 | 3 | ||
| 4 | use super::{raw, Spawner}; | 4 | #[cfg(feature = "executor-thread")] |
| 5 | pub use thread::*; | ||
| 6 | #[cfg(feature = "executor-thread")] | ||
| 7 | mod thread { | ||
| 8 | use std::marker::PhantomData; | ||
| 9 | use std::sync::{Condvar, Mutex}; | ||
| 5 | 10 | ||
| 6 | /// Single-threaded std-based executor. | 11 | #[cfg(feature = "nightly")] |
| 7 | pub struct Executor { | 12 | pub use embassy_macros::main_std as main; |
| 8 | inner: raw::Executor, | 13 | |
| 9 | not_send: PhantomData<*mut ()>, | 14 | use crate::raw::{Pender, PenderInner}; |
| 10 | signaler: &'static Signaler, | 15 | use crate::{raw, Spawner}; |
| 11 | } | ||
| 12 | 16 | ||
| 13 | impl Executor { | 17 | #[derive(Copy, Clone)] |
| 14 | /// Create a new Executor. | 18 | pub(crate) struct ThreadPender(&'static Signaler); |
| 15 | pub fn new() -> Self { | 19 | |
| 16 | let signaler = &*Box::leak(Box::new(Signaler::new())); | 20 | impl ThreadPender { |
| 17 | Self { | 21 | #[allow(unused)] |
| 18 | inner: raw::Executor::new( | 22 | pub(crate) fn pend(self) { |
| 19 | |p| unsafe { | 23 | self.0.signal() |
| 20 | let s = &*(p as *const () as *const Signaler); | ||
| 21 | s.signal() | ||
| 22 | }, | ||
| 23 | signaler as *const _ as _, | ||
| 24 | ), | ||
| 25 | not_send: PhantomData, | ||
| 26 | signaler, | ||
| 27 | } | 24 | } |
| 28 | } | 25 | } |
| 29 | 26 | ||
| 30 | /// Run the executor. | 27 | /// Single-threaded std-based executor. |
| 31 | /// | 28 | pub struct Executor { |
| 32 | /// The `init` closure is called with a [`Spawner`] that spawns tasks on | 29 | inner: raw::Executor, |
| 33 | /// this executor. Use it to spawn the initial task(s). After `init` returns, | 30 | not_send: PhantomData<*mut ()>, |
| 34 | /// the executor starts running the tasks. | 31 | signaler: &'static Signaler, |
| 35 | /// | 32 | } |
| 36 | /// To spawn more tasks later, you may keep copies of the [`Spawner`] (it is `Copy`), | ||
| 37 | /// for example by passing it as an argument to the initial tasks. | ||
| 38 | /// | ||
| 39 | /// This function requires `&'static mut self`. This means you have to store the | ||
| 40 | /// Executor instance in a place where it'll live forever and grants you mutable | ||
| 41 | /// access. There's a few ways to do this: | ||
| 42 | /// | ||
| 43 | /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe) | ||
| 44 | /// - a `static mut` (unsafe) | ||
| 45 | /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) | ||
| 46 | /// | ||
| 47 | /// This function never returns. | ||
| 48 | pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! { | ||
| 49 | init(self.inner.spawner()); | ||
| 50 | 33 | ||
| 51 | loop { | 34 | impl Executor { |
| 52 | unsafe { self.inner.poll() }; | 35 | /// Create a new Executor. |
| 53 | self.signaler.wait() | 36 | pub fn new() -> Self { |
| 37 | let signaler = &*Box::leak(Box::new(Signaler::new())); | ||
| 38 | Self { | ||
| 39 | inner: raw::Executor::new(Pender(PenderInner::Thread(ThreadPender(signaler)))), | ||
| 40 | not_send: PhantomData, | ||
| 41 | signaler, | ||
| 42 | } | ||
| 54 | } | 43 | } |
| 55 | } | ||
| 56 | } | ||
| 57 | 44 | ||
| 58 | struct Signaler { | 45 | /// Run the executor. |
| 59 | mutex: Mutex<bool>, | 46 | /// |
| 60 | condvar: Condvar, | 47 | /// The `init` closure is called with a [`Spawner`] that spawns tasks on |
| 61 | } | 48 | /// this executor. Use it to spawn the initial task(s). After `init` returns, |
| 49 | /// the executor starts running the tasks. | ||
| 50 | /// | ||
| 51 | /// To spawn more tasks later, you may keep copies of the [`Spawner`] (it is `Copy`), | ||
| 52 | /// for example by passing it as an argument to the initial tasks. | ||
| 53 | /// | ||
| 54 | /// This function requires `&'static mut self`. This means you have to store the | ||
| 55 | /// Executor instance in a place where it'll live forever and grants you mutable | ||
| 56 | /// access. There's a few ways to do this: | ||
| 57 | /// | ||
| 58 | /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe) | ||
| 59 | /// - a `static mut` (unsafe) | ||
| 60 | /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) | ||
| 61 | /// | ||
| 62 | /// This function never returns. | ||
| 63 | pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! { | ||
| 64 | init(self.inner.spawner()); | ||
| 62 | 65 | ||
| 63 | impl Signaler { | 66 | loop { |
| 64 | fn new() -> Self { | 67 | unsafe { self.inner.poll() }; |
| 65 | Self { | 68 | self.signaler.wait() |
| 66 | mutex: Mutex::new(false), | 69 | } |
| 67 | condvar: Condvar::new(), | ||
| 68 | } | 70 | } |
| 69 | } | 71 | } |
| 70 | 72 | ||
| 71 | fn wait(&self) { | 73 | struct Signaler { |
| 72 | let mut signaled = self.mutex.lock().unwrap(); | 74 | mutex: Mutex<bool>, |
| 73 | while !*signaled { | 75 | condvar: Condvar, |
| 74 | signaled = self.condvar.wait(signaled).unwrap(); | ||
| 75 | } | ||
| 76 | *signaled = false; | ||
| 77 | } | 76 | } |
| 78 | 77 | ||
| 79 | fn signal(&self) { | 78 | impl Signaler { |
| 80 | let mut signaled = self.mutex.lock().unwrap(); | 79 | fn new() -> Self { |
| 81 | *signaled = true; | 80 | Self { |
| 82 | self.condvar.notify_one(); | 81 | mutex: Mutex::new(false), |
| 82 | condvar: Condvar::new(), | ||
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 86 | fn wait(&self) { | ||
| 87 | let mut signaled = self.mutex.lock().unwrap(); | ||
| 88 | while !*signaled { | ||
| 89 | signaled = self.condvar.wait(signaled).unwrap(); | ||
| 90 | } | ||
| 91 | *signaled = false; | ||
| 92 | } | ||
| 93 | |||
| 94 | fn signal(&self) { | ||
| 95 | let mut signaled = self.mutex.lock().unwrap(); | ||
| 96 | *signaled = true; | ||
| 97 | self.condvar.notify_one(); | ||
| 98 | } | ||
| 83 | } | 99 | } |
| 84 | } | 100 | } |
diff --git a/embassy-executor/src/arch/wasm.rs b/embassy-executor/src/arch/wasm.rs index 98091cfbb..08ab16b99 100644 --- a/embassy-executor/src/arch/wasm.rs +++ b/embassy-executor/src/arch/wasm.rs | |||
| @@ -1,74 +1,88 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | #[cfg(feature = "executor-interrupt")] |
| 2 | compile_error!("`executor-interrupt` is not supported with `arch-wasm`."); | ||
| 2 | 3 | ||
| 3 | use js_sys::Promise; | 4 | #[cfg(feature = "executor-thread")] |
| 4 | use wasm_bindgen::prelude::*; | 5 | pub use thread::*; |
| 6 | #[cfg(feature = "executor-thread")] | ||
| 7 | mod thread { | ||
| 5 | 8 | ||
| 6 | use super::raw::util::UninitCell; | 9 | use core::marker::PhantomData; |
| 7 | use super::raw::{self}; | ||
| 8 | use super::Spawner; | ||
| 9 | 10 | ||
| 10 | /// WASM executor, wasm_bindgen to schedule tasks on the JS event loop. | 11 | #[cfg(feature = "nightly")] |
| 11 | pub struct Executor { | 12 | pub use embassy_macros::main_wasm as main; |
| 12 | inner: raw::Executor, | 13 | use js_sys::Promise; |
| 13 | ctx: &'static WasmContext, | 14 | use wasm_bindgen::prelude::*; |
| 14 | not_send: PhantomData<*mut ()>, | ||
| 15 | } | ||
| 16 | 15 | ||
| 17 | pub(crate) struct WasmContext { | 16 | use crate::raw::util::UninitCell; |
| 18 | promise: Promise, | 17 | use crate::raw::{Pender, PenderInner}; |
| 19 | closure: UninitCell<Closure<dyn FnMut(JsValue)>>, | 18 | use crate::{raw, Spawner}; |
| 20 | } | 19 | |
| 20 | /// WASM executor, wasm_bindgen to schedule tasks on the JS event loop. | ||
| 21 | pub struct Executor { | ||
| 22 | inner: raw::Executor, | ||
| 23 | ctx: &'static WasmContext, | ||
| 24 | not_send: PhantomData<*mut ()>, | ||
| 25 | } | ||
| 26 | |||
| 27 | pub(crate) struct WasmContext { | ||
| 28 | promise: Promise, | ||
| 29 | closure: UninitCell<Closure<dyn FnMut(JsValue)>>, | ||
| 30 | } | ||
| 31 | |||
| 32 | #[derive(Copy, Clone)] | ||
| 33 | pub(crate) struct ThreadPender(&'static WasmContext); | ||
| 21 | 34 | ||
| 22 | impl WasmContext { | 35 | impl ThreadPender { |
| 23 | pub fn new() -> Self { | 36 | #[allow(unused)] |
| 24 | Self { | 37 | pub(crate) fn pend(self) { |
| 25 | promise: Promise::resolve(&JsValue::undefined()), | 38 | let _ = self.0.promise.then(unsafe { self.0.closure.as_mut() }); |
| 26 | closure: UninitCell::uninit(), | ||
| 27 | } | 39 | } |
| 28 | } | 40 | } |
| 29 | } | ||
| 30 | 41 | ||
| 31 | impl Executor { | 42 | impl WasmContext { |
| 32 | /// Create a new Executor. | 43 | pub fn new() -> Self { |
| 33 | pub fn new() -> Self { | 44 | Self { |
| 34 | let ctx = &*Box::leak(Box::new(WasmContext::new())); | 45 | promise: Promise::resolve(&JsValue::undefined()), |
| 35 | let inner = raw::Executor::new( | 46 | closure: UninitCell::uninit(), |
| 36 | |p| unsafe { | 47 | } |
| 37 | let ctx = &*(p as *const () as *const WasmContext); | ||
| 38 | let _ = ctx.promise.then(ctx.closure.as_mut()); | ||
| 39 | }, | ||
| 40 | ctx as *const _ as _, | ||
| 41 | ); | ||
| 42 | Self { | ||
| 43 | inner, | ||
| 44 | not_send: PhantomData, | ||
| 45 | ctx, | ||
| 46 | } | 48 | } |
| 47 | } | 49 | } |
| 48 | 50 | ||
| 49 | /// Run the executor. | 51 | impl Executor { |
| 50 | /// | 52 | /// Create a new Executor. |
| 51 | /// The `init` closure is called with a [`Spawner`] that spawns tasks on | 53 | pub fn new() -> Self { |
| 52 | /// this executor. Use it to spawn the initial task(s). After `init` returns, | 54 | let ctx = &*Box::leak(Box::new(WasmContext::new())); |
| 53 | /// the executor starts running the tasks. | 55 | Self { |
| 54 | /// | 56 | inner: raw::Executor::new(Pender(PenderInner::Thread(ThreadPender(ctx)))), |
| 55 | /// To spawn more tasks later, you may keep copies of the [`Spawner`] (it is `Copy`), | 57 | not_send: PhantomData, |
| 56 | /// for example by passing it as an argument to the initial tasks. | 58 | ctx, |
| 57 | /// | 59 | } |
| 58 | /// This function requires `&'static mut self`. This means you have to store the | 60 | } |
| 59 | /// Executor instance in a place where it'll live forever and grants you mutable | 61 | |
| 60 | /// access. There's a few ways to do this: | 62 | /// Run the executor. |
| 61 | /// | 63 | /// |
| 62 | /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe) | 64 | /// The `init` closure is called with a [`Spawner`] that spawns tasks on |
| 63 | /// - a `static mut` (unsafe) | 65 | /// this executor. Use it to spawn the initial task(s). After `init` returns, |
| 64 | /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) | 66 | /// the executor starts running the tasks. |
| 65 | pub fn start(&'static mut self, init: impl FnOnce(Spawner)) { | 67 | /// |
| 66 | unsafe { | 68 | /// To spawn more tasks later, you may keep copies of the [`Spawner`] (it is `Copy`), |
| 67 | let executor = &self.inner; | 69 | /// for example by passing it as an argument to the initial tasks. |
| 68 | self.ctx.closure.write(Closure::new(move |_| { | 70 | /// |
| 69 | executor.poll(); | 71 | /// This function requires `&'static mut self`. This means you have to store the |
| 70 | })); | 72 | /// Executor instance in a place where it'll live forever and grants you mutable |
| 71 | init(self.inner.spawner()); | 73 | /// access. There's a few ways to do this: |
| 74 | /// | ||
| 75 | /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe) | ||
| 76 | /// - a `static mut` (unsafe) | ||
| 77 | /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) | ||
| 78 | pub fn start(&'static mut self, init: impl FnOnce(Spawner)) { | ||
| 79 | unsafe { | ||
| 80 | let executor = &self.inner; | ||
| 81 | self.ctx.closure.write(Closure::new(move |_| { | ||
| 82 | executor.poll(); | ||
| 83 | })); | ||
| 84 | init(self.inner.spawner()); | ||
| 85 | } | ||
| 72 | } | 86 | } |
| 73 | } | 87 | } |
| 74 | } | 88 | } |
diff --git a/embassy-executor/src/arch/xtensa.rs b/embassy-executor/src/arch/xtensa.rs index 4ee0d9f78..61ea92c16 100644 --- a/embassy-executor/src/arch/xtensa.rs +++ b/embassy-executor/src/arch/xtensa.rs | |||
| @@ -1,73 +1,84 @@ | |||
| 1 | use core::marker::PhantomData; | 1 | #[cfg(feature = "executor-interrupt")] |
| 2 | use core::ptr; | 2 | compile_error!("`executor-interrupt` is not supported with `arch-xtensa`."); |
| 3 | use core::sync::atomic::{AtomicBool, Ordering}; | ||
| 4 | 3 | ||
| 5 | use super::{raw, Spawner}; | 4 | #[cfg(feature = "executor-thread")] |
| 5 | pub use thread::*; | ||
| 6 | #[cfg(feature = "executor-thread")] | ||
| 7 | mod thread { | ||
| 8 | use core::marker::PhantomData; | ||
| 9 | use core::sync::atomic::{AtomicBool, Ordering}; | ||
| 6 | 10 | ||
| 7 | /// global atomic used to keep track of whether there is work to do since sev() is not available on Xtensa | 11 | use crate::raw::{Pender, PenderInner}; |
| 8 | /// | 12 | use crate::{raw, Spawner}; |
| 9 | static SIGNAL_WORK_THREAD_MODE: AtomicBool = AtomicBool::new(false); | ||
| 10 | 13 | ||
| 11 | /// Xtensa Executor | 14 | #[derive(Copy, Clone)] |
| 12 | pub struct Executor { | 15 | pub(crate) struct ThreadPender; |
| 13 | inner: raw::Executor, | ||
| 14 | not_send: PhantomData<*mut ()>, | ||
| 15 | } | ||
| 16 | 16 | ||
| 17 | impl Executor { | 17 | impl ThreadPender { |
| 18 | /// Create a new Executor. | 18 | #[allow(unused)] |
| 19 | pub fn new() -> Self { | 19 | pub(crate) fn pend(self) { |
| 20 | Self { | 20 | SIGNAL_WORK_THREAD_MODE.store(true, core::sync::atomic::Ordering::SeqCst); |
| 21 | // use Signal_Work_Thread_Mode as substitute for local interrupt register | ||
| 22 | inner: raw::Executor::new( | ||
| 23 | |_| { | ||
| 24 | SIGNAL_WORK_THREAD_MODE.store(true, Ordering::SeqCst); | ||
| 25 | }, | ||
| 26 | ptr::null_mut(), | ||
| 27 | ), | ||
| 28 | not_send: PhantomData, | ||
| 29 | } | 21 | } |
| 30 | } | 22 | } |
| 31 | 23 | ||
| 32 | /// Run the executor. | 24 | /// global atomic used to keep track of whether there is work to do since sev() is not available on Xtensa |
| 33 | /// | 25 | static SIGNAL_WORK_THREAD_MODE: AtomicBool = AtomicBool::new(false); |
| 34 | /// The `init` closure is called with a [`Spawner`] that spawns tasks on | 26 | |
| 35 | /// this executor. Use it to spawn the initial task(s). After `init` returns, | 27 | /// Xtensa Executor |
| 36 | /// the executor starts running the tasks. | 28 | pub struct Executor { |
| 37 | /// | 29 | inner: raw::Executor, |
| 38 | /// To spawn more tasks later, you may keep copies of the [`Spawner`] (it is `Copy`), | 30 | not_send: PhantomData<*mut ()>, |
| 39 | /// for example by passing it as an argument to the initial tasks. | 31 | } |
| 40 | /// | 32 | |
| 41 | /// This function requires `&'static mut self`. This means you have to store the | 33 | impl Executor { |
| 42 | /// Executor instance in a place where it'll live forever and grants you mutable | 34 | /// Create a new Executor. |
| 43 | /// access. There's a few ways to do this: | 35 | pub fn new() -> Self { |
| 44 | /// | 36 | Self { |
| 45 | /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe) | 37 | inner: raw::Executor::new(Pender(PenderInner::Thread(ThreadPender))), |
| 46 | /// - a `static mut` (unsafe) | 38 | not_send: PhantomData, |
| 47 | /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) | 39 | } |
| 48 | /// | 40 | } |
| 49 | /// This function never returns. | 41 | |
| 50 | pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! { | 42 | /// Run the executor. |
| 51 | init(self.inner.spawner()); | 43 | /// |
| 44 | /// The `init` closure is called with a [`Spawner`] that spawns tasks on | ||
| 45 | /// this executor. Use it to spawn the initial task(s). After `init` returns, | ||
| 46 | /// the executor starts running the tasks. | ||
| 47 | /// | ||
| 48 | /// To spawn more tasks later, you may keep copies of the [`Spawner`] (it is `Copy`), | ||
| 49 | /// for example by passing it as an argument to the initial tasks. | ||
| 50 | /// | ||
| 51 | /// This function requires `&'static mut self`. This means you have to store the | ||
| 52 | /// Executor instance in a place where it'll live forever and grants you mutable | ||
| 53 | /// access. There's a few ways to do this: | ||
| 54 | /// | ||
| 55 | /// - a [StaticCell](https://docs.rs/static_cell/latest/static_cell/) (safe) | ||
| 56 | /// - a `static mut` (unsafe) | ||
| 57 | /// - a local variable in a function you know never returns (like `fn main() -> !`), upgrading its lifetime with `transmute`. (unsafe) | ||
| 58 | /// | ||
| 59 | /// This function never returns. | ||
| 60 | pub fn run(&'static mut self, init: impl FnOnce(Spawner)) -> ! { | ||
| 61 | init(self.inner.spawner()); | ||
| 52 | 62 | ||
| 53 | loop { | 63 | loop { |
| 54 | unsafe { | 64 | unsafe { |
| 55 | self.inner.poll(); | 65 | self.inner.poll(); |
| 56 | // we do not care about race conditions between the load and store operations, interrupts | 66 | // we do not care about race conditions between the load and store operations, interrupts |
| 57 | // will only set this value to true. | 67 | // will only set this value to true. |
| 58 | // if there is work to do, loop back to polling | 68 | // if there is work to do, loop back to polling |
| 59 | // TODO can we relax this? | 69 | // TODO can we relax this? |
| 60 | critical_section::with(|_| { | 70 | critical_section::with(|_| { |
| 61 | if SIGNAL_WORK_THREAD_MODE.load(Ordering::SeqCst) { | 71 | if SIGNAL_WORK_THREAD_MODE.load(Ordering::SeqCst) { |
| 62 | SIGNAL_WORK_THREAD_MODE.store(false, Ordering::SeqCst); | 72 | SIGNAL_WORK_THREAD_MODE.store(false, Ordering::SeqCst); |
| 63 | } else { | 73 | } else { |
| 64 | // waiti sets the PS.INTLEVEL when slipping into sleep | 74 | // waiti sets the PS.INTLEVEL when slipping into sleep |
| 65 | // because critical sections in Xtensa are implemented via increasing | 75 | // because critical sections in Xtensa are implemented via increasing |
| 66 | // PS.INTLEVEL the critical section ends here | 76 | // PS.INTLEVEL the critical section ends here |
| 67 | // take care not add code after `waiti` if it needs to be inside the CS | 77 | // take care not add code after `waiti` if it needs to be inside the CS |
| 68 | core::arch::asm!("waiti 0"); // critical section ends here | 78 | core::arch::asm!("waiti 0"); // critical section ends here |
| 69 | } | 79 | } |
| 70 | }); | 80 | }); |
| 81 | } | ||
| 71 | } | 82 | } |
| 72 | } | 83 | } |
| 73 | } | 84 | } |
diff --git a/embassy-executor/src/lib.rs b/embassy-executor/src/lib.rs index 8707995b4..3ce687eb6 100644 --- a/embassy-executor/src/lib.rs +++ b/embassy-executor/src/lib.rs | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | #![cfg_attr(not(any(feature = "std", feature = "wasm")), no_std)] | 1 | #![cfg_attr(not(any(feature = "arch-std", feature = "arch-wasm")), no_std)] |
| 2 | #![cfg_attr(all(feature = "nightly", target_arch = "xtensa"), feature(asm_experimental_arch))] | 2 | #![cfg_attr(all(feature = "nightly", feature = "arch-xtensa"), feature(asm_experimental_arch))] |
| 3 | #![allow(clippy::new_without_default)] | 3 | #![allow(clippy::new_without_default)] |
| 4 | #![doc = include_str!("../README.md")] | 4 | #![doc = include_str!("../README.md")] |
| 5 | #![warn(missing_docs)] | 5 | #![warn(missing_docs)] |
| @@ -10,41 +10,35 @@ pub(crate) mod fmt; | |||
| 10 | #[cfg(feature = "nightly")] | 10 | #[cfg(feature = "nightly")] |
| 11 | pub use embassy_macros::task; | 11 | pub use embassy_macros::task; |
| 12 | 12 | ||
| 13 | cfg_if::cfg_if! { | 13 | macro_rules! check_at_most_one { |
| 14 | if #[cfg(cortex_m)] { | 14 | (@amo [$($feats:literal)*] [] [$($res:tt)*]) => { |
| 15 | #[path="arch/cortex_m.rs"] | 15 | #[cfg(any($($res)*))] |
| 16 | mod arch; | 16 | compile_error!(concat!("At most one of these features can be enabled at the same time:", $(" `", $feats, "`",)*)); |
| 17 | pub use arch::*; | 17 | }; |
| 18 | #[cfg(feature = "nightly")] | 18 | (@amo $feats:tt [$curr:literal $($rest:literal)*] [$($res:tt)*]) => { |
| 19 | pub use embassy_macros::main_cortex_m as main; | 19 | check_at_most_one!(@amo $feats [$($rest)*] [$($res)* $(all(feature=$curr, feature=$rest),)*]); |
| 20 | } | 20 | }; |
| 21 | else if #[cfg(target_arch="riscv32")] { | 21 | ($($f:literal),*$(,)?) => { |
| 22 | #[path="arch/riscv32.rs"] | 22 | check_at_most_one!(@amo [$($f)*] [$($f)*] []); |
| 23 | mod arch; | 23 | }; |
| 24 | pub use arch::*; | ||
| 25 | #[cfg(feature = "nightly")] | ||
| 26 | pub use embassy_macros::main_riscv as main; | ||
| 27 | } | ||
| 28 | else if #[cfg(all(target_arch="xtensa", feature = "nightly"))] { | ||
| 29 | #[path="arch/xtensa.rs"] | ||
| 30 | mod arch; | ||
| 31 | pub use arch::*; | ||
| 32 | } | ||
| 33 | else if #[cfg(feature="wasm")] { | ||
| 34 | #[path="arch/wasm.rs"] | ||
| 35 | mod arch; | ||
| 36 | pub use arch::*; | ||
| 37 | #[cfg(feature = "nightly")] | ||
| 38 | pub use embassy_macros::main_wasm as main; | ||
| 39 | } | ||
| 40 | else if #[cfg(feature="std")] { | ||
| 41 | #[path="arch/std.rs"] | ||
| 42 | mod arch; | ||
| 43 | pub use arch::*; | ||
| 44 | #[cfg(feature = "nightly")] | ||
| 45 | pub use embassy_macros::main_std as main; | ||
| 46 | } | ||
| 47 | } | 24 | } |
| 25 | check_at_most_one!("arch-cortex-m", "arch-riscv32", "arch-xtensa", "arch-std", "arch-wasm",); | ||
| 26 | |||
| 27 | #[cfg(feature = "_arch")] | ||
| 28 | #[cfg_attr(feature = "arch-cortex-m", path = "arch/cortex_m.rs")] | ||
| 29 | #[cfg_attr(feature = "arch-riscv32", path = "arch/riscv32.rs")] | ||
| 30 | #[cfg_attr(feature = "arch-xtensa", path = "arch/xtensa.rs")] | ||
| 31 | #[cfg_attr(feature = "arch-std", path = "arch/std.rs")] | ||
| 32 | #[cfg_attr(feature = "arch-wasm", path = "arch/wasm.rs")] | ||
| 33 | mod arch; | ||
| 34 | |||
| 35 | #[cfg(feature = "_arch")] | ||
| 36 | pub use arch::*; | ||
| 37 | |||
| 38 | pub mod raw; | ||
| 39 | |||
| 40 | mod spawner; | ||
| 41 | pub use spawner::*; | ||
| 48 | 42 | ||
| 49 | /// Implementation details for embassy macros. | 43 | /// Implementation details for embassy macros. |
| 50 | /// Do not use. Used for macros and HALs only. Not covered by semver guarantees. | 44 | /// Do not use. Used for macros and HALs only. Not covered by semver guarantees. |
| @@ -72,8 +66,3 @@ pub mod _export { | |||
| 72 | ($($tt:tt)*) => {}; | 66 | ($($tt:tt)*) => {}; |
| 73 | } | 67 | } |
| 74 | } | 68 | } |
| 75 | |||
| 76 | pub mod raw; | ||
| 77 | |||
| 78 | mod spawner; | ||
| 79 | pub use spawner::*; | ||
diff --git a/embassy-executor/src/raw/mod.rs b/embassy-executor/src/raw/mod.rs index 72c367c33..f6c66da5a 100644 --- a/embassy-executor/src/raw/mod.rs +++ b/embassy-executor/src/raw/mod.rs | |||
| @@ -19,7 +19,6 @@ use core::marker::PhantomData; | |||
| 19 | use core::mem; | 19 | use core::mem; |
| 20 | use core::pin::Pin; | 20 | use core::pin::Pin; |
| 21 | use core::ptr::NonNull; | 21 | use core::ptr::NonNull; |
| 22 | use core::sync::atomic::AtomicPtr; | ||
| 23 | use core::task::{Context, Poll}; | 22 | use core::task::{Context, Poll}; |
| 24 | 23 | ||
| 25 | use atomic_polyfill::{AtomicU32, Ordering}; | 24 | use atomic_polyfill::{AtomicU32, Ordering}; |
| @@ -290,10 +289,60 @@ impl<F: Future + 'static, const N: usize> TaskPool<F, N> { | |||
| 290 | } | 289 | } |
| 291 | } | 290 | } |
| 292 | 291 | ||
| 292 | #[derive(Clone, Copy)] | ||
| 293 | pub(crate) enum PenderInner { | ||
| 294 | #[cfg(feature = "executor-thread")] | ||
| 295 | Thread(crate::arch::ThreadPender), | ||
| 296 | #[cfg(feature = "executor-interrupt")] | ||
| 297 | Interrupt(crate::arch::InterruptPender), | ||
| 298 | #[cfg(feature = "pender-callback")] | ||
| 299 | Callback { func: fn(*mut ()), context: *mut () }, | ||
| 300 | } | ||
| 301 | |||
| 302 | unsafe impl Send for PenderInner {} | ||
| 303 | unsafe impl Sync for PenderInner {} | ||
| 304 | |||
| 305 | /// Platform/architecture-specific action executed when an executor has pending work. | ||
| 306 | /// | ||
| 307 | /// When a task within an executor is woken, the `Pender` is called. This does a | ||
| 308 | /// platform/architecture-specific action to signal there is pending work in the executor. | ||
| 309 | /// When this happens, you must arrange for [`Executor::poll`] to be called. | ||
| 310 | /// | ||
| 311 | /// You can think of it as a waker, but for the whole executor. | ||
| 312 | pub struct Pender(pub(crate) PenderInner); | ||
| 313 | |||
| 314 | impl Pender { | ||
| 315 | /// Create a `Pender` that will call an arbitrary function pointer. | ||
| 316 | /// | ||
| 317 | /// # Arguments | ||
| 318 | /// | ||
| 319 | /// - `func`: The function pointer to call. | ||
| 320 | /// - `context`: Opaque context pointer, that will be passed to the function pointer. | ||
| 321 | #[cfg(feature = "pender-callback")] | ||
| 322 | pub fn new_from_callback(func: fn(*mut ()), context: *mut ()) -> Self { | ||
| 323 | Self(PenderInner::Callback { | ||
| 324 | func, | ||
| 325 | context: context.into(), | ||
| 326 | }) | ||
| 327 | } | ||
| 328 | } | ||
| 329 | |||
| 330 | impl Pender { | ||
| 331 | pub(crate) fn pend(&self) { | ||
| 332 | match self.0 { | ||
| 333 | #[cfg(feature = "executor-thread")] | ||
| 334 | PenderInner::Thread(x) => x.pend(), | ||
| 335 | #[cfg(feature = "executor-interrupt")] | ||
| 336 | PenderInner::Interrupt(x) => x.pend(), | ||
| 337 | #[cfg(feature = "pender-callback")] | ||
| 338 | PenderInner::Callback { func, context } => func(context), | ||
| 339 | } | ||
| 340 | } | ||
| 341 | } | ||
| 342 | |||
| 293 | pub(crate) struct SyncExecutor { | 343 | pub(crate) struct SyncExecutor { |
| 294 | run_queue: RunQueue, | 344 | run_queue: RunQueue, |
| 295 | signal_fn: fn(*mut ()), | 345 | pender: Pender, |
| 296 | signal_ctx: AtomicPtr<()>, | ||
| 297 | 346 | ||
| 298 | #[cfg(feature = "integrated-timers")] | 347 | #[cfg(feature = "integrated-timers")] |
| 299 | pub(crate) timer_queue: timer_queue::TimerQueue, | 348 | pub(crate) timer_queue: timer_queue::TimerQueue, |
| @@ -302,16 +351,13 @@ pub(crate) struct SyncExecutor { | |||
| 302 | } | 351 | } |
| 303 | 352 | ||
| 304 | impl SyncExecutor { | 353 | impl SyncExecutor { |
| 305 | pub(crate) fn new(signal_fn: fn(*mut ()), signal_ctx: *mut ()) -> Self { | 354 | pub(crate) fn new(pender: Pender) -> Self { |
| 306 | #[cfg(feature = "integrated-timers")] | 355 | #[cfg(feature = "integrated-timers")] |
| 307 | let alarm = unsafe { unwrap!(driver::allocate_alarm()) }; | 356 | let alarm = unsafe { unwrap!(driver::allocate_alarm()) }; |
| 308 | #[cfg(feature = "integrated-timers")] | ||
| 309 | driver::set_alarm_callback(alarm, signal_fn, signal_ctx); | ||
| 310 | 357 | ||
| 311 | Self { | 358 | Self { |
| 312 | run_queue: RunQueue::new(), | 359 | run_queue: RunQueue::new(), |
| 313 | signal_fn, | 360 | pender, |
| 314 | signal_ctx: AtomicPtr::new(signal_ctx), | ||
| 315 | 361 | ||
| 316 | #[cfg(feature = "integrated-timers")] | 362 | #[cfg(feature = "integrated-timers")] |
| 317 | timer_queue: timer_queue::TimerQueue::new(), | 363 | timer_queue: timer_queue::TimerQueue::new(), |
| @@ -332,10 +378,16 @@ impl SyncExecutor { | |||
| 332 | trace::task_ready_begin(task.as_ptr() as u32); | 378 | trace::task_ready_begin(task.as_ptr() as u32); |
| 333 | 379 | ||
| 334 | if self.run_queue.enqueue(cs, task) { | 380 | if self.run_queue.enqueue(cs, task) { |
| 335 | (self.signal_fn)(self.signal_ctx.load(Ordering::Relaxed)) | 381 | self.pender.pend(); |
| 336 | } | 382 | } |
| 337 | } | 383 | } |
| 338 | 384 | ||
| 385 | #[cfg(feature = "integrated-timers")] | ||
| 386 | fn alarm_callback(ctx: *mut ()) { | ||
| 387 | let this: &Self = unsafe { &*(ctx as *const Self) }; | ||
| 388 | this.pender.pend(); | ||
| 389 | } | ||
| 390 | |||
| 339 | pub(super) unsafe fn spawn(&'static self, task: TaskRef) { | 391 | pub(super) unsafe fn spawn(&'static self, task: TaskRef) { |
| 340 | task.header().executor.set(Some(self)); | 392 | task.header().executor.set(Some(self)); |
| 341 | 393 | ||
| @@ -351,6 +403,9 @@ impl SyncExecutor { | |||
| 351 | /// | 403 | /// |
| 352 | /// Same as [`Executor::poll`], plus you must only call this on the thread this executor was created. | 404 | /// Same as [`Executor::poll`], plus you must only call this on the thread this executor was created. |
| 353 | pub(crate) unsafe fn poll(&'static self) { | 405 | pub(crate) unsafe fn poll(&'static self) { |
| 406 | #[cfg(feature = "integrated-timers")] | ||
| 407 | driver::set_alarm_callback(self.alarm, Self::alarm_callback, self as *const _ as *mut ()); | ||
| 408 | |||
| 354 | #[allow(clippy::never_loop)] | 409 | #[allow(clippy::never_loop)] |
| 355 | loop { | 410 | loop { |
| 356 | #[cfg(feature = "integrated-timers")] | 411 | #[cfg(feature = "integrated-timers")] |
| @@ -417,14 +472,14 @@ impl SyncExecutor { | |||
| 417 | /// | 472 | /// |
| 418 | /// - To get the executor to do work, call `poll()`. This will poll all queued tasks (all tasks | 473 | /// - To get the executor to do work, call `poll()`. This will poll all queued tasks (all tasks |
| 419 | /// that "want to run"). | 474 | /// that "want to run"). |
| 420 | /// - You must supply a `signal_fn`. The executor will call it to notify you it has work | 475 | /// - You must supply a [`Pender`]. The executor will call it to notify you it has work |
| 421 | /// to do. You must arrange for `poll()` to be called as soon as possible. | 476 | /// to do. You must arrange for `poll()` to be called as soon as possible. |
| 422 | /// | 477 | /// |
| 423 | /// `signal_fn` can be called from *any* context: any thread, any interrupt priority | 478 | /// The [`Pender`] can be called from *any* context: any thread, any interrupt priority |
| 424 | /// level, etc. It may be called synchronously from any `Executor` method call as well. | 479 | /// level, etc. It may be called synchronously from any `Executor` method call as well. |
| 425 | /// You must deal with this correctly. | 480 | /// You must deal with this correctly. |
| 426 | /// | 481 | /// |
| 427 | /// In particular, you must NOT call `poll` directly from `signal_fn`, as this violates | 482 | /// In particular, you must NOT call `poll` directly from the pender callback, as this violates |
| 428 | /// the requirement for `poll` to not be called reentrantly. | 483 | /// the requirement for `poll` to not be called reentrantly. |
| 429 | #[repr(transparent)] | 484 | #[repr(transparent)] |
| 430 | pub struct Executor { | 485 | pub struct Executor { |
| @@ -437,15 +492,15 @@ impl Executor { | |||
| 437 | pub(crate) unsafe fn wrap(inner: &SyncExecutor) -> &Self { | 492 | pub(crate) unsafe fn wrap(inner: &SyncExecutor) -> &Self { |
| 438 | mem::transmute(inner) | 493 | mem::transmute(inner) |
| 439 | } | 494 | } |
| 495 | |||
| 440 | /// Create a new executor. | 496 | /// Create a new executor. |
| 441 | /// | 497 | /// |
| 442 | /// When the executor has work to do, it will call `signal_fn` with | 498 | /// When the executor has work to do, it will call the [`Pender`]. |
| 443 | /// `signal_ctx` as argument. | ||
| 444 | /// | 499 | /// |
| 445 | /// See [`Executor`] docs for details on `signal_fn`. | 500 | /// See [`Executor`] docs for details on `Pender`. |
| 446 | pub fn new(signal_fn: fn(*mut ()), signal_ctx: *mut ()) -> Self { | 501 | pub fn new(pender: Pender) -> Self { |
| 447 | Self { | 502 | Self { |
| 448 | inner: SyncExecutor::new(signal_fn, signal_ctx), | 503 | inner: SyncExecutor::new(pender), |
| 449 | _not_sync: PhantomData, | 504 | _not_sync: PhantomData, |
| 450 | } | 505 | } |
| 451 | } | 506 | } |
| @@ -468,16 +523,16 @@ impl Executor { | |||
| 468 | /// This loops over all tasks that are queued to be polled (i.e. they're | 523 | /// This loops over all tasks that are queued to be polled (i.e. they're |
| 469 | /// freshly spawned or they've been woken). Other tasks are not polled. | 524 | /// freshly spawned or they've been woken). Other tasks are not polled. |
| 470 | /// | 525 | /// |
| 471 | /// You must call `poll` after receiving a call to `signal_fn`. It is OK | 526 | /// You must call `poll` after receiving a call to the [`Pender`]. It is OK |
| 472 | /// to call `poll` even when not requested by `signal_fn`, but it wastes | 527 | /// to call `poll` even when not requested by the `Pender`, but it wastes |
| 473 | /// energy. | 528 | /// energy. |
| 474 | /// | 529 | /// |
| 475 | /// # Safety | 530 | /// # Safety |
| 476 | /// | 531 | /// |
| 477 | /// You must NOT call `poll` reentrantly on the same executor. | 532 | /// You must NOT call `poll` reentrantly on the same executor. |
| 478 | /// | 533 | /// |
| 479 | /// In particular, note that `poll` may call `signal_fn` synchronously. Therefore, you | 534 | /// In particular, note that `poll` may call the `Pender` synchronously. Therefore, you |
| 480 | /// must NOT directly call `poll()` from your `signal_fn`. Instead, `signal_fn` has to | 535 | /// must NOT directly call `poll()` from the `Pender` callback. Instead, the callback has to |
| 481 | /// somehow schedule for `poll()` to be called later, at a time you know for sure there's | 536 | /// somehow schedule for `poll()` to be called later, at a time you know for sure there's |
| 482 | /// no `poll()` already running. | 537 | /// no `poll()` already running. |
| 483 | pub unsafe fn poll(&'static self) { | 538 | pub unsafe fn poll(&'static self) { |
diff --git a/examples/boot/application/nrf/Cargo.toml b/examples/boot/application/nrf/Cargo.toml index 888993255..e75c73cbd 100644 --- a/examples/boot/application/nrf/Cargo.toml +++ b/examples/boot/application/nrf/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync" } | 8 | embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync" } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly"] } | 10 | embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly"] } |
| 11 | embassy-nrf = { version = "0.1.0", path = "../../../../embassy-nrf", features = ["time-driver-rtc1", "gpiote", "nightly"] } | 11 | embassy-nrf = { version = "0.1.0", path = "../../../../embassy-nrf", features = ["time-driver-rtc1", "gpiote", "nightly"] } |
| 12 | embassy-boot = { version = "0.1.0", path = "../../../../embassy-boot/boot" } | 12 | embassy-boot = { version = "0.1.0", path = "../../../../embassy-boot/boot" } |
diff --git a/examples/boot/application/rp/Cargo.toml b/examples/boot/application/rp/Cargo.toml index 8d826790b..8de2d2ebd 100644 --- a/examples/boot/application/rp/Cargo.toml +++ b/examples/boot/application/rp/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync" } | 8 | embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync" } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers", "arch-cortex-m", "executor-thread"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly"] } | 10 | embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly"] } |
| 11 | embassy-rp = { version = "0.1.0", path = "../../../../embassy-rp", features = ["time-driver", "unstable-traits", "nightly"] } | 11 | embassy-rp = { version = "0.1.0", path = "../../../../embassy-rp", features = ["time-driver", "unstable-traits", "nightly"] } |
| 12 | embassy-boot-rp = { version = "0.1.0", path = "../../../../embassy-boot/rp" } | 12 | embassy-boot-rp = { version = "0.1.0", path = "../../../../embassy-boot/rp" } |
diff --git a/examples/boot/application/stm32f3/Cargo.toml b/examples/boot/application/stm32f3/Cargo.toml index aa279fb76..083607de5 100644 --- a/examples/boot/application/stm32f3/Cargo.toml +++ b/examples/boot/application/stm32f3/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] } | 8 | embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32f303re", "time-driver-any", "exti"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32f303re", "time-driver-any", "exti"] } |
| 12 | embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" } | 12 | embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" } |
diff --git a/examples/boot/application/stm32f7/Cargo.toml b/examples/boot/application/stm32f7/Cargo.toml index 1ec0643a6..74f508515 100644 --- a/examples/boot/application/stm32f7/Cargo.toml +++ b/examples/boot/application/stm32f7/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] } | 8 | embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32f767zi", "time-driver-any", "exti"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32f767zi", "time-driver-any", "exti"] } |
| 12 | embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" } | 12 | embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" } |
diff --git a/examples/boot/application/stm32h7/Cargo.toml b/examples/boot/application/stm32h7/Cargo.toml index a4eefe2a5..898b9a47e 100644 --- a/examples/boot/application/stm32h7/Cargo.toml +++ b/examples/boot/application/stm32h7/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync" } | 8 | embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync" } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32h743zi", "time-driver-any", "exti"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32h743zi", "time-driver-any", "exti"] } |
| 12 | embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" } | 12 | embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" } |
diff --git a/examples/boot/application/stm32l0/Cargo.toml b/examples/boot/application/stm32l0/Cargo.toml index 36eada29b..e142c8481 100644 --- a/examples/boot/application/stm32l0/Cargo.toml +++ b/examples/boot/application/stm32l0/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] } | 8 | embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l072cz", "time-driver-any", "exti", "memory-x"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l072cz", "time-driver-any", "exti", "memory-x"] } |
| 12 | embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" } | 12 | embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" } |
diff --git a/examples/boot/application/stm32l1/Cargo.toml b/examples/boot/application/stm32l1/Cargo.toml index 67efda748..f0e92e1ac 100644 --- a/examples/boot/application/stm32l1/Cargo.toml +++ b/examples/boot/application/stm32l1/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] } | 8 | embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l151cb-a", "time-driver-any", "exti"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l151cb-a", "time-driver-any", "exti"] } |
| 12 | embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" } | 12 | embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" } |
diff --git a/examples/boot/application/stm32l4/Cargo.toml b/examples/boot/application/stm32l4/Cargo.toml index 4b2e02dd2..87689e9a9 100644 --- a/examples/boot/application/stm32l4/Cargo.toml +++ b/examples/boot/application/stm32l4/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] } | 8 | embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l475vg", "time-driver-any", "exti"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32l475vg", "time-driver-any", "exti"] } |
| 12 | embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" } | 12 | embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" } |
diff --git a/examples/boot/application/stm32wl/Cargo.toml b/examples/boot/application/stm32wl/Cargo.toml index fecbfc51d..a6708bf51 100644 --- a/examples/boot/application/stm32wl/Cargo.toml +++ b/examples/boot/application/stm32wl/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] } | 8 | embassy-sync = { version = "0.1.0", path = "../../../../embassy-sync", features = ["defmt"] } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["nightly", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "nightly", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.1.0", path = "../../../../embassy-time", features = ["nightly", "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32wl55jc-cm4", "time-driver-any", "exti"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../../../embassy-stm32", features = ["unstable-traits", "nightly", "stm32wl55jc-cm4", "time-driver-any", "exti"] } |
| 12 | embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" } | 12 | embassy-boot-stm32 = { version = "0.1.0", path = "../../../../embassy-boot/stm32" } |
diff --git a/examples/nrf-rtos-trace/Cargo.toml b/examples/nrf-rtos-trace/Cargo.toml index d8c24dfad..7910b372a 100644 --- a/examples/nrf-rtos-trace/Cargo.toml +++ b/examples/nrf-rtos-trace/Cargo.toml | |||
| @@ -17,7 +17,7 @@ log = [ | |||
| 17 | 17 | ||
| 18 | [dependencies] | 18 | [dependencies] |
| 19 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync" } | 19 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync" } |
| 20 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features=["rtos-trace", "rtos-trace-interrupt", "integrated-timers"] } | 20 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "rtos-trace", "rtos-trace-interrupt", "integrated-timers"] } |
| 21 | embassy-time = { version = "0.1.0", path = "../../embassy-time" } | 21 | embassy-time = { version = "0.1.0", path = "../../embassy-time" } |
| 22 | embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } | 22 | embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } |
| 23 | 23 | ||
diff --git a/examples/nrf52840/Cargo.toml b/examples/nrf52840/Cargo.toml index cc88d92c7..3ece24066 100644 --- a/examples/nrf52840/Cargo.toml +++ b/examples/nrf52840/Cargo.toml | |||
| @@ -12,7 +12,7 @@ nightly = ["embassy-executor/nightly", "embassy-nrf/nightly", "embassy-net/night | |||
| 12 | [dependencies] | 12 | [dependencies] |
| 13 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 13 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| 14 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } | 14 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } |
| 15 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } | 15 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } |
| 16 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | 16 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } |
| 17 | embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } | 17 | embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } |
| 18 | embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"], optional = true } | 18 | embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet"], optional = true } |
diff --git a/examples/nrf5340/Cargo.toml b/examples/nrf5340/Cargo.toml index e88ddf2f7..4134db46f 100644 --- a/examples/nrf5340/Cargo.toml +++ b/examples/nrf5340/Cargo.toml | |||
| @@ -9,7 +9,7 @@ embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | |||
| 9 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = [ | 9 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = [ |
| 10 | "defmt", | 10 | "defmt", |
| 11 | ] } | 11 | ] } |
| 12 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = [ | 12 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", |
| 13 | "nightly", | 13 | "nightly", |
| 14 | "defmt", | 14 | "defmt", |
| 15 | "integrated-timers", | 15 | "integrated-timers", |
diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index 1e8870ed7..aea61eec5 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml | |||
| @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" | |||
| 7 | 7 | ||
| 8 | [dependencies] | 8 | [dependencies] |
| 9 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } | 9 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } |
| 10 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } | 10 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 11 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } | 11 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } |
| 12 | embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["defmt", "unstable-traits", "nightly", "unstable-pac", "time-driver", "pio", "critical-section-impl"] } | 12 | embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["defmt", "unstable-traits", "nightly", "unstable-pac", "time-driver", "pio", "critical-section-impl"] } |
| 13 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 13 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } |
diff --git a/examples/std/Cargo.toml b/examples/std/Cargo.toml index 8087df09a..ff08e378c 100644 --- a/examples/std/Cargo.toml +++ b/examples/std/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["log"] } | 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["log"] } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["log", "std", "nightly", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-std", "executor-thread", "log", "nightly", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["log", "std", "nightly"] } | 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["log", "std", "nightly"] } |
| 11 | embassy-net = { version = "0.1.0", path = "../../embassy-net", features=[ "std", "nightly", "log", "medium-ethernet", "tcp", "udp", "dns", "dhcpv4", "unstable-traits", "proto-ipv6"] } | 11 | embassy-net = { version = "0.1.0", path = "../../embassy-net", features=[ "std", "nightly", "log", "medium-ethernet", "tcp", "udp", "dns", "dhcpv4", "unstable-traits", "proto-ipv6"] } |
| 12 | embassy-net-driver = { version = "0.1.0", path = "../../embassy-net-driver" } | 12 | embassy-net-driver = { version = "0.1.0", path = "../../embassy-net-driver" } |
diff --git a/examples/stm32c0/Cargo.toml b/examples/stm32c0/Cargo.toml index 0095a680c..3b1d888f6 100644 --- a/examples/stm32c0/Cargo.toml +++ b/examples/stm32c0/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } | 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32c031c6", "memory-x", "unstable-pac", "exti"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32c031c6", "memory-x", "unstable-pac", "exti"] } |
| 12 | 12 | ||
diff --git a/examples/stm32f0/Cargo.toml b/examples/stm32f0/Cargo.toml index 89d99b6d3..5c82c5579 100644 --- a/examples/stm32f0/Cargo.toml +++ b/examples/stm32f0/Cargo.toml | |||
| @@ -13,7 +13,7 @@ defmt = "0.3" | |||
| 13 | defmt-rtt = "0.4" | 13 | defmt-rtt = "0.4" |
| 14 | panic-probe = "0.3" | 14 | panic-probe = "0.3" |
| 15 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } | 15 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } |
| 16 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } | 16 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } |
| 17 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 17 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 18 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "memory-x", "stm32f091rc", "time-driver-any", "exti", "unstable-pac"] } | 18 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "memory-x", "stm32f091rc", "time-driver-any", "exti", "unstable-pac"] } |
| 19 | static_cell = "1.0" | 19 | static_cell = "1.0" |
diff --git a/examples/stm32f0/src/bin/multiprio.rs b/examples/stm32f0/src/bin/multiprio.rs index e0dc8c989..430a805fc 100644 --- a/examples/stm32f0/src/bin/multiprio.rs +++ b/examples/stm32f0/src/bin/multiprio.rs | |||
| @@ -62,7 +62,7 @@ use core::mem; | |||
| 62 | use cortex_m::peripheral::NVIC; | 62 | use cortex_m::peripheral::NVIC; |
| 63 | use cortex_m_rt::entry; | 63 | use cortex_m_rt::entry; |
| 64 | use defmt::*; | 64 | use defmt::*; |
| 65 | use embassy_stm32::executor::{Executor, InterruptExecutor}; | 65 | use embassy_executor::{Executor, InterruptExecutor}; |
| 66 | use embassy_stm32::interrupt; | 66 | use embassy_stm32::interrupt; |
| 67 | use embassy_stm32::pac::Interrupt; | 67 | use embassy_stm32::pac::Interrupt; |
| 68 | use embassy_time::{Duration, Instant, Timer}; | 68 | use embassy_time::{Duration, Instant, Timer}; |
diff --git a/examples/stm32f1/Cargo.toml b/examples/stm32f1/Cargo.toml index 53f369b3a..387af783a 100644 --- a/examples/stm32f1/Cargo.toml +++ b/examples/stm32f1/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } | 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f103c8", "unstable-pac", "memory-x", "time-driver-any"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f103c8", "unstable-pac", "memory-x", "time-driver-any"] } |
| 12 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 12 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } |
diff --git a/examples/stm32f2/Cargo.toml b/examples/stm32f2/Cargo.toml index afaf9a0c9..ffb232310 100644 --- a/examples/stm32f2/Cargo.toml +++ b/examples/stm32f2/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } | 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f207zg", "unstable-pac", "memory-x", "time-driver-any", "exti"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f207zg", "unstable-pac", "memory-x", "time-driver-any", "exti"] } |
| 12 | 12 | ||
diff --git a/examples/stm32f3/Cargo.toml b/examples/stm32f3/Cargo.toml index 69ebef786..38f11201d 100644 --- a/examples/stm32f3/Cargo.toml +++ b/examples/stm32f3/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } | 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f303ze", "unstable-pac", "memory-x", "time-driver-any", "exti"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f303ze", "unstable-pac", "memory-x", "time-driver-any", "exti"] } |
| 12 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 12 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } |
diff --git a/examples/stm32f3/src/bin/multiprio.rs b/examples/stm32f3/src/bin/multiprio.rs index 77df51ac7..5d010f799 100644 --- a/examples/stm32f3/src/bin/multiprio.rs +++ b/examples/stm32f3/src/bin/multiprio.rs | |||
| @@ -62,7 +62,7 @@ use core::mem; | |||
| 62 | use cortex_m::peripheral::NVIC; | 62 | use cortex_m::peripheral::NVIC; |
| 63 | use cortex_m_rt::entry; | 63 | use cortex_m_rt::entry; |
| 64 | use defmt::*; | 64 | use defmt::*; |
| 65 | use embassy_stm32::executor::{Executor, InterruptExecutor}; | 65 | use embassy_executor::{Executor, InterruptExecutor}; |
| 66 | use embassy_stm32::interrupt; | 66 | use embassy_stm32::interrupt; |
| 67 | use embassy_stm32::pac::Interrupt; | 67 | use embassy_stm32::pac::Interrupt; |
| 68 | use embassy_time::{Duration, Instant, Timer}; | 68 | use embassy_time::{Duration, Instant, Timer}; |
diff --git a/examples/stm32f4/Cargo.toml b/examples/stm32f4/Cargo.toml index 7a7bab5bb..d967d8501 100644 --- a/examples/stm32f4/Cargo.toml +++ b/examples/stm32f4/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } | 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt", "integrated-timers", "arch-cortex-m", "executor-thread", "executor-interrupt"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "unstable-traits", "defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "unstable-traits", "defmt", "stm32f429zi", "unstable-pac", "memory-x", "time-driver-any", "exti"] } |
| 12 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 12 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } |
diff --git a/examples/stm32f4/src/bin/multiprio.rs b/examples/stm32f4/src/bin/multiprio.rs index 77df51ac7..5d010f799 100644 --- a/examples/stm32f4/src/bin/multiprio.rs +++ b/examples/stm32f4/src/bin/multiprio.rs | |||
| @@ -62,7 +62,7 @@ use core::mem; | |||
| 62 | use cortex_m::peripheral::NVIC; | 62 | use cortex_m::peripheral::NVIC; |
| 63 | use cortex_m_rt::entry; | 63 | use cortex_m_rt::entry; |
| 64 | use defmt::*; | 64 | use defmt::*; |
| 65 | use embassy_stm32::executor::{Executor, InterruptExecutor}; | 65 | use embassy_executor::{Executor, InterruptExecutor}; |
| 66 | use embassy_stm32::interrupt; | 66 | use embassy_stm32::interrupt; |
| 67 | use embassy_stm32::pac::Interrupt; | 67 | use embassy_stm32::pac::Interrupt; |
| 68 | use embassy_time::{Duration, Instant, Timer}; | 68 | use embassy_time::{Duration, Instant, Timer}; |
diff --git a/examples/stm32f7/Cargo.toml b/examples/stm32f7/Cargo.toml index ea4cbd808..74e7bf53d 100644 --- a/examples/stm32f7/Cargo.toml +++ b/examples/stm32f7/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } | 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f767zi", "unstable-pac", "time-driver-any", "exti"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32f767zi", "unstable-pac", "time-driver-any", "exti"] } |
| 12 | embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] } | 12 | embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] } |
diff --git a/examples/stm32g0/Cargo.toml b/examples/stm32g0/Cargo.toml index e7273c9fc..03bdbcea3 100644 --- a/examples/stm32g0/Cargo.toml +++ b/examples/stm32g0/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } | 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32g071rb", "memory-x", "unstable-pac", "exti"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32g071rb", "memory-x", "unstable-pac", "exti"] } |
| 12 | 12 | ||
diff --git a/examples/stm32g4/Cargo.toml b/examples/stm32g4/Cargo.toml index 8a57a8ef0..4e4150350 100644 --- a/examples/stm32g4/Cargo.toml +++ b/examples/stm32g4/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } | 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32g491re", "memory-x", "unstable-pac", "exti"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "time-driver-any", "stm32g491re", "memory-x", "unstable-pac", "exti"] } |
| 12 | embassy-hal-common = {version = "0.1.0", path = "../../embassy-hal-common" } | 12 | embassy-hal-common = {version = "0.1.0", path = "../../embassy-hal-common" } |
diff --git a/examples/stm32h7/Cargo.toml b/examples/stm32h7/Cargo.toml index a04134789..d0d6a9497 100644 --- a/examples/stm32h7/Cargo.toml +++ b/examples/stm32h7/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } | 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "unstable-traits", "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h743bi", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32h743bi", "time-driver-any", "exti", "unstable-pac", "unstable-traits"] } |
| 12 | embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "unstable-traits", "proto-ipv6"] } | 12 | embassy-net = { path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet", "unstable-traits", "proto-ipv6"] } |
diff --git a/examples/stm32l0/Cargo.toml b/examples/stm32l0/Cargo.toml index 86933a629..413d5c18f 100644 --- a/examples/stm32l0/Cargo.toml +++ b/examples/stm32l0/Cargo.toml | |||
| @@ -10,7 +10,7 @@ nightly = ["embassy-stm32/nightly", "embassy-lora", "lorawan-device", "lorawan", | |||
| 10 | 10 | ||
| 11 | [dependencies] | 11 | [dependencies] |
| 12 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } | 12 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } |
| 13 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } | 13 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 14 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 14 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 15 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-any", "exti", "unstable-traits", "memory-x"] } | 15 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["defmt", "stm32l072cz", "time-driver-any", "exti", "unstable-traits", "memory-x"] } |
| 16 | embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["sx127x", "time", "defmt"], optional = true} | 16 | embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["sx127x", "time", "defmt"], optional = true} |
diff --git a/examples/stm32l1/Cargo.toml b/examples/stm32l1/Cargo.toml index 6e3b2103c..cd9508d57 100644 --- a/examples/stm32l1/Cargo.toml +++ b/examples/stm32l1/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } | 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32l151cb-a", "time-driver-any", "memory-x"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32l151cb-a", "time-driver-any", "memory-x"] } |
| 12 | 12 | ||
diff --git a/examples/stm32l4/Cargo.toml b/examples/stm32l4/Cargo.toml index 644c90b1a..7c254eba3 100644 --- a/examples/stm32l4/Cargo.toml +++ b/examples/stm32l4/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } | 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 11 | embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" } | 11 | embassy-embedded-hal = { version = "0.1.0", path = "../../embassy-embedded-hal" } |
| 12 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l4s5vi", "time-driver-any", "exti", "unstable-traits"] } | 12 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l4s5vi", "time-driver-any", "exti", "unstable-traits"] } |
diff --git a/examples/stm32l5/Cargo.toml b/examples/stm32l5/Cargo.toml index f880328dc..1c662b9da 100644 --- a/examples/stm32l5/Cargo.toml +++ b/examples/stm32l5/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } | 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l552ze", "time-driver-any", "exti", "unstable-traits", "memory-x"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32l552ze", "time-driver-any", "exti", "unstable-traits", "memory-x"] } |
| 12 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 12 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } |
diff --git a/examples/stm32u5/Cargo.toml b/examples/stm32u5/Cargo.toml index 2b02eda92..ebef0a4f7 100644 --- a/examples/stm32u5/Cargo.toml +++ b/examples/stm32u5/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } | 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32u585ai", "time-driver-any", "memory-x" ] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "stm32u585ai", "time-driver-any", "memory-x" ] } |
| 12 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } | 12 | embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } |
diff --git a/examples/stm32wb/Cargo.toml b/examples/stm32wb/Cargo.toml index e27b4527c..ddf9729e6 100644 --- a/examples/stm32wb/Cargo.toml +++ b/examples/stm32wb/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } | 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32wb55cc", "time-driver-any", "exti"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32wb55cc", "time-driver-any", "exti"] } |
| 12 | 12 | ||
diff --git a/examples/stm32wl/Cargo.toml b/examples/stm32wl/Cargo.toml index 690481bbf..9fc7e0f4a 100644 --- a/examples/stm32wl/Cargo.toml +++ b/examples/stm32wl/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } | 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } | 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime", "tick-hz-32_768"] } |
| 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32wl55jc-cm4", "time-driver-any", "memory-x", "subghz", "unstable-pac", "exti"] } | 11 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "stm32wl55jc-cm4", "time-driver-any", "memory-x", "subghz", "unstable-pac", "exti"] } |
| 12 | embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["stm32wl", "time", "defmt"] } | 12 | embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["stm32wl", "time", "defmt"] } |
diff --git a/examples/wasm/Cargo.toml b/examples/wasm/Cargo.toml index e0e799a34..430d0b4c7 100644 --- a/examples/wasm/Cargo.toml +++ b/examples/wasm/Cargo.toml | |||
| @@ -9,7 +9,7 @@ crate-type = ["cdylib"] | |||
| 9 | 9 | ||
| 10 | [dependencies] | 10 | [dependencies] |
| 11 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["log"] } | 11 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["log"] } |
| 12 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["log", "wasm", "nightly", "integrated-timers"] } | 12 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-wasm", "executor-thread", "log", "nightly", "integrated-timers"] } |
| 13 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["log", "wasm", "nightly"] } | 13 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["log", "wasm", "nightly"] } |
| 14 | 14 | ||
| 15 | wasm-logger = "0.2.0" | 15 | wasm-logger = "0.2.0" |
diff --git a/tests/nrf/Cargo.toml b/tests/nrf/Cargo.toml index 2a4e8cf41..912749e5d 100644 --- a/tests/nrf/Cargo.toml +++ b/tests/nrf/Cargo.toml | |||
| @@ -7,7 +7,7 @@ license = "MIT OR Apache-2.0" | |||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 8 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
| 9 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt", "nightly"] } | 9 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt", "nightly"] } |
| 10 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "nightly", "integrated-timers"] } | 10 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "nightly", "integrated-timers"] } |
| 11 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "nightly", "defmt-timestamp-uptime"] } | 11 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "nightly", "defmt-timestamp-uptime"] } |
| 12 | embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nightly", "unstable-traits", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } | 12 | embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nightly", "unstable-traits", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } |
| 13 | embedded-io = { version = "0.4.0", features = ["async"] } | 13 | embedded-io = { version = "0.4.0", features = ["async"] } |
diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml index 572a9ce88..eb447be35 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml | |||
| @@ -6,7 +6,7 @@ license = "MIT OR Apache-2.0" | |||
| 6 | 6 | ||
| 7 | [dependencies] | 7 | [dependencies] |
| 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } | 8 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } |
| 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } | 9 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt"] } | 10 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt"] } |
| 11 | embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "time-driver", "critical-section-impl"] } | 11 | embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "time-driver", "critical-section-impl"] } |
| 12 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } | 12 | embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } |
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml index 08a775eae..17b640797 100644 --- a/tests/stm32/Cargo.toml +++ b/tests/stm32/Cargo.toml | |||
| @@ -15,7 +15,7 @@ stm32u585ai = ["embassy-stm32/stm32u585ai"] # IoT board | |||
| 15 | 15 | ||
| 16 | [dependencies] | 16 | [dependencies] |
| 17 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } | 17 | embassy-sync = { version = "0.1.0", path = "../../embassy-sync", features = ["defmt"] } |
| 18 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["defmt", "integrated-timers"] } | 18 | embassy-executor = { version = "0.1.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } |
| 19 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "tick-hz-32_768"] } | 19 | embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["defmt", "tick-hz-32_768"] } |
| 20 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "memory-x", "time-driver-tim2"] } | 20 | embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "memory-x", "time-driver-tim2"] } |
| 21 | 21 | ||
