diff options
| -rw-r--r-- | embassy-hal-common/src/peripheral.rs | 18 | ||||
| -rw-r--r-- | embassy-hal-common/src/usb/mod.rs | 5 | ||||
| -rw-r--r-- | embassy-nrf/src/buffered_uarte.rs | 30 | ||||
| -rw-r--r-- | embassy-stm32/src/eth/v2/mod.rs | 4 |
4 files changed, 28 insertions, 29 deletions
diff --git a/embassy-hal-common/src/peripheral.rs b/embassy-hal-common/src/peripheral.rs index 46c6ebeee..dcf9d3a27 100644 --- a/embassy-hal-common/src/peripheral.rs +++ b/embassy-hal-common/src/peripheral.rs | |||
| @@ -50,19 +50,23 @@ pub(crate) fn can_be_preempted(irq: &impl Interrupt) -> bool { | |||
| 50 | } | 50 | } |
| 51 | 51 | ||
| 52 | impl<'a, S: PeripheralState> PeripheralMutex<'a, S> { | 52 | impl<'a, S: PeripheralState> PeripheralMutex<'a, S> { |
| 53 | /// Create a new `PeripheralMutex` wrapping `irq`, with the initial state `state`. | 53 | /// Create a new `PeripheralMutex` wrapping `irq`, with `init` initializing the initial state. |
| 54 | /// | 54 | /// |
| 55 | /// self requires `state` to live for `'static`, because if the `PeripheralMutex` is leaked, the | 55 | /// self requires `S` to live for `'static`, because if the `PeripheralMutex` is leaked, the |
| 56 | /// interrupt won't be disabled, which may try accessing the state at any time. To use non-`'static` | 56 | /// interrupt won't be disabled, which may try accessing the state at any time. To use non-`'static` |
| 57 | /// state, see [`Self::new_unchecked`]. | 57 | /// state, see [`Self::new_unchecked`]. |
| 58 | /// | 58 | /// |
| 59 | /// Registers `on_interrupt` as the `irq`'s handler, and enables it. | 59 | /// Registers `on_interrupt` as the `irq`'s handler, and enables it. |
| 60 | pub fn new(storage: &'a mut StateStorage<S>, state: S, irq: S::Interrupt) -> Self | 60 | pub fn new( |
| 61 | irq: S::Interrupt, | ||
| 62 | storage: &'a mut StateStorage<S>, | ||
| 63 | init: impl FnOnce() -> S, | ||
| 64 | ) -> Self | ||
| 61 | where | 65 | where |
| 62 | 'a: 'static, | 66 | 'a: 'static, |
| 63 | { | 67 | { |
| 64 | // safety: safe because state is `'static`. | 68 | // safety: safe because state is `'static`. |
| 65 | unsafe { Self::new_unchecked(storage, state, irq) } | 69 | unsafe { Self::new_unchecked(irq, storage, init) } |
| 66 | } | 70 | } |
| 67 | 71 | ||
| 68 | /// Create a `PeripheralMutex` without requiring the state is `'static`. | 72 | /// Create a `PeripheralMutex` without requiring the state is `'static`. |
| @@ -72,9 +76,9 @@ impl<'a, S: PeripheralState> PeripheralMutex<'a, S> { | |||
| 72 | /// # Safety | 76 | /// # Safety |
| 73 | /// The created instance must not be leaked (its `drop` must run). | 77 | /// The created instance must not be leaked (its `drop` must run). |
| 74 | pub unsafe fn new_unchecked( | 78 | pub unsafe fn new_unchecked( |
| 75 | storage: &'a mut StateStorage<S>, | ||
| 76 | state: S, | ||
| 77 | irq: S::Interrupt, | 79 | irq: S::Interrupt, |
| 80 | storage: &'a mut StateStorage<S>, | ||
| 81 | init: impl FnOnce() -> S, | ||
| 78 | ) -> Self { | 82 | ) -> Self { |
| 79 | if can_be_preempted(&irq) { | 83 | if can_be_preempted(&irq) { |
| 80 | panic!("`PeripheralMutex` cannot be created in an interrupt with higher priority than the interrupt it wraps"); | 84 | panic!("`PeripheralMutex` cannot be created in an interrupt with higher priority than the interrupt it wraps"); |
| @@ -84,7 +88,7 @@ impl<'a, S: PeripheralState> PeripheralMutex<'a, S> { | |||
| 84 | 88 | ||
| 85 | // Safety: The pointer is valid and not used by anyone else | 89 | // Safety: The pointer is valid and not used by anyone else |
| 86 | // because we have the `&mut StateStorage`. | 90 | // because we have the `&mut StateStorage`. |
| 87 | state_ptr.write(state); | 91 | state_ptr.write(init()); |
| 88 | 92 | ||
| 89 | irq.disable(); | 93 | irq.disable(); |
| 90 | irq.set_handler(|p| { | 94 | irq.set_handler(|p| { |
diff --git a/embassy-hal-common/src/usb/mod.rs b/embassy-hal-common/src/usb/mod.rs index ae9f26075..70a74bd52 100644 --- a/embassy-hal-common/src/usb/mod.rs +++ b/embassy-hal-common/src/usb/mod.rs | |||
| @@ -67,12 +67,11 @@ where | |||
| 67 | class_set: S, | 67 | class_set: S, |
| 68 | irq: I, | 68 | irq: I, |
| 69 | ) -> Self { | 69 | ) -> Self { |
| 70 | let initial_state = StateInner { | 70 | let mutex = PeripheralMutex::new_unchecked(irq, &mut state.0, || StateInner { |
| 71 | device, | 71 | device, |
| 72 | classes: class_set.into_class_set(), | 72 | classes: class_set.into_class_set(), |
| 73 | _interrupt: PhantomData, | 73 | _interrupt: PhantomData, |
| 74 | }; | 74 | }); |
| 75 | let mutex = PeripheralMutex::new_unchecked(&mut state.0, initial_state, irq); | ||
| 76 | Self { | 75 | Self { |
| 77 | inner: RefCell::new(mutex), | 76 | inner: RefCell::new(mutex), |
| 78 | } | 77 | } |
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 642c30185..048c36d39 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs | |||
| @@ -155,23 +155,21 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 155 | ppi_ch2.set_task(Task::from_reg(&r.tasks_stoprx)); | 155 | ppi_ch2.set_task(Task::from_reg(&r.tasks_stoprx)); |
| 156 | ppi_ch2.enable(); | 156 | ppi_ch2.enable(); |
| 157 | 157 | ||
| 158 | let initial_state = StateInner { | ||
| 159 | phantom: PhantomData, | ||
| 160 | timer, | ||
| 161 | _ppi_ch1: ppi_ch1, | ||
| 162 | _ppi_ch2: ppi_ch2, | ||
| 163 | |||
| 164 | rx: RingBuffer::new(rx_buffer), | ||
| 165 | rx_state: RxState::Idle, | ||
| 166 | rx_waker: WakerRegistration::new(), | ||
| 167 | |||
| 168 | tx: RingBuffer::new(tx_buffer), | ||
| 169 | tx_state: TxState::Idle, | ||
| 170 | tx_waker: WakerRegistration::new(), | ||
| 171 | }; | ||
| 172 | |||
| 173 | Self { | 158 | Self { |
| 174 | inner: PeripheralMutex::new_unchecked(&mut state.0, initial_state, irq), | 159 | inner: PeripheralMutex::new_unchecked(irq, &mut state.0, move || StateInner { |
| 160 | phantom: PhantomData, | ||
| 161 | timer, | ||
| 162 | _ppi_ch1: ppi_ch1, | ||
| 163 | _ppi_ch2: ppi_ch2, | ||
| 164 | |||
| 165 | rx: RingBuffer::new(rx_buffer), | ||
| 166 | rx_state: RxState::Idle, | ||
| 167 | rx_waker: WakerRegistration::new(), | ||
| 168 | |||
| 169 | tx: RingBuffer::new(tx_buffer), | ||
| 170 | tx_state: TxState::Idle, | ||
| 171 | tx_waker: WakerRegistration::new(), | ||
| 172 | }), | ||
| 175 | } | 173 | } |
| 176 | } | 174 | } |
| 177 | 175 | ||
diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs index cfb461ab3..c1956aa16 100644 --- a/embassy-stm32/src/eth/v2/mod.rs +++ b/embassy-stm32/src/eth/v2/mod.rs | |||
| @@ -78,10 +78,8 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, P, TX, RX> { | |||
| 78 | tx_d1.configure(); | 78 | tx_d1.configure(); |
| 79 | tx_en.configure(); | 79 | tx_en.configure(); |
| 80 | 80 | ||
| 81 | let inner = Inner::new(peri); | ||
| 82 | |||
| 83 | // NOTE(unsafe) We are ourselves not leak-safe. | 81 | // NOTE(unsafe) We are ourselves not leak-safe. |
| 84 | let state = PeripheralMutex::new_unchecked(&mut state.0, inner, interrupt); | 82 | let state = PeripheralMutex::new_unchecked(interrupt, &mut state.0, || Inner::new(peri)); |
| 85 | 83 | ||
| 86 | // NOTE(unsafe) We have exclusive access to the registers | 84 | // NOTE(unsafe) We have exclusive access to the registers |
| 87 | let dma = ETH.ethernet_dma(); | 85 | let dma = ETH.ethernet_dma(); |
