diff options
| -rw-r--r-- | embassy-extras/src/peripheral.rs | 66 | ||||
| -rw-r--r-- | embassy-extras/src/peripheral_shared.rs | 52 | ||||
| -rw-r--r-- | embassy-extras/src/usb/mod.rs | 9 | ||||
| -rw-r--r-- | embassy-nrf/src/buffered_uarte.rs | 13 | ||||
| -rw-r--r-- | embassy-stm32/src/eth/v2/mod.rs | 8 |
5 files changed, 84 insertions, 64 deletions
diff --git a/embassy-extras/src/peripheral.rs b/embassy-extras/src/peripheral.rs index 725a58a46..1868edd7d 100644 --- a/embassy-extras/src/peripheral.rs +++ b/embassy-extras/src/peripheral.rs | |||
| @@ -6,42 +6,20 @@ use cortex_m::peripheral::scb::{Exception, SystemHandler, VectActive}; | |||
| 6 | use cortex_m::peripheral::{NVIC, SCB}; | 6 | use cortex_m::peripheral::{NVIC, SCB}; |
| 7 | use embassy::interrupt::{Interrupt, InterruptExt}; | 7 | use embassy::interrupt::{Interrupt, InterruptExt}; |
| 8 | 8 | ||
| 9 | /// A version of `PeripheralState` without the `'static` bound, | ||
| 10 | /// for cases where the compiler can't statically make sure | ||
| 11 | /// that `on_interrupt` doesn't reference anything which might be invalidated. | ||
| 12 | /// | ||
| 13 | /// # Safety | ||
| 14 | /// When types implementing this trait are used with `PeripheralMutex`, | ||
| 15 | /// no fields referenced by `on_interrupt`'s lifetimes must end without first calling `Drop` on the `PeripheralMutex`. | ||
| 16 | pub unsafe trait PeripheralStateUnchecked: Send { | ||
| 17 | type Interrupt: Interrupt; | ||
| 18 | fn on_interrupt(&mut self); | ||
| 19 | } | ||
| 20 | |||
| 21 | /// A type which can be used as state with `PeripheralMutex`. | 9 | /// A type which can be used as state with `PeripheralMutex`. |
| 22 | /// | 10 | /// |
| 23 | /// It needs to be `Send` because `&mut` references are sent back and forth between the 'thread' which owns the `PeripheralMutex` and the interrupt, | 11 | /// It needs to be `Send` because `&mut` references are sent back and forth between the 'thread' which owns the `PeripheralMutex` and the interrupt, |
| 24 | /// and `&mut T` is only `Send` where `T: Send`. | 12 | /// and `&mut T` is only `Send` where `T: Send`. |
| 25 | /// | 13 | /// |
| 26 | /// It also requires `'static`, because although `Pin` guarantees that the memory of the state won't be invalidated, | 14 | /// It also requires `'static` to be used safely with `PeripheralMutex::register_interrupt`, |
| 15 | /// because although `Pin` guarantees that the memory of the state won't be invalidated, | ||
| 27 | /// it doesn't guarantee that the lifetime will last. | 16 | /// it doesn't guarantee that the lifetime will last. |
| 28 | pub trait PeripheralState: Send + 'static { | 17 | pub trait PeripheralState: Send { |
| 29 | type Interrupt: Interrupt; | 18 | type Interrupt: Interrupt; |
| 30 | fn on_interrupt(&mut self); | 19 | fn on_interrupt(&mut self); |
| 31 | } | 20 | } |
| 32 | 21 | ||
| 33 | // SAFETY: `T` has to live for `'static` to implement `PeripheralState`, thus its lifetime cannot end. | 22 | pub struct PeripheralMutex<S: PeripheralState> { |
| 34 | unsafe impl<T> PeripheralStateUnchecked for T | ||
| 35 | where | ||
| 36 | T: PeripheralState, | ||
| 37 | { | ||
| 38 | type Interrupt = T::Interrupt; | ||
| 39 | fn on_interrupt(&mut self) { | ||
| 40 | self.on_interrupt() | ||
| 41 | } | ||
| 42 | } | ||
| 43 | |||
| 44 | pub struct PeripheralMutex<S: PeripheralStateUnchecked> { | ||
| 45 | state: UnsafeCell<S>, | 23 | state: UnsafeCell<S>, |
| 46 | 24 | ||
| 47 | irq_setup_done: bool, | 25 | irq_setup_done: bool, |
| @@ -98,7 +76,25 @@ pub(crate) fn can_be_preempted(irq: &impl Interrupt) -> bool { | |||
| 98 | } | 76 | } |
| 99 | } | 77 | } |
| 100 | 78 | ||
| 101 | impl<S: PeripheralStateUnchecked> PeripheralMutex<S> { | 79 | impl<S: PeripheralState + 'static> PeripheralMutex<S> { |
| 80 | /// Registers `on_interrupt` as the wrapped interrupt's interrupt handler and enables it. | ||
| 81 | /// | ||
| 82 | /// This requires this `PeripheralMutex`'s `PeripheralState` to live for `'static`, | ||
| 83 | /// because `Pin` only guarantees that it's memory won't be repurposed, | ||
| 84 | /// not that it's lifetime will last. | ||
| 85 | /// | ||
| 86 | /// To use non-`'static` `PeripheralState`, use the unsafe `register_interrupt_unchecked`. | ||
| 87 | /// | ||
| 88 | /// Note: `'static` doesn't mean it _has_ to live for the entire program, like an `&'static T`; | ||
| 89 | /// it just means it _can_ live for the entire program - for example, `u8` lives for `'static`. | ||
| 90 | pub fn register_interrupt(self: Pin<&mut Self>) { | ||
| 91 | // SAFETY: `S: 'static`, so there's no way it's lifetime can expire. | ||
| 92 | unsafe { self.register_interrupt_unchecked() } | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | impl<S: PeripheralState> PeripheralMutex<S> { | ||
| 97 | /// Create a new `PeripheralMutex` wrapping `irq`, with the initial state `state`. | ||
| 102 | pub fn new(state: S, irq: S::Interrupt) -> Self { | 98 | pub fn new(state: S, irq: S::Interrupt) -> Self { |
| 103 | if can_be_preempted(&irq) { | 99 | if can_be_preempted(&irq) { |
| 104 | panic!("`PeripheralMutex` cannot be created in an interrupt with higher priority than the interrupt it wraps"); | 100 | panic!("`PeripheralMutex` cannot be created in an interrupt with higher priority than the interrupt it wraps"); |
| @@ -114,8 +110,18 @@ impl<S: PeripheralStateUnchecked> PeripheralMutex<S> { | |||
| 114 | } | 110 | } |
| 115 | } | 111 | } |
| 116 | 112 | ||
| 117 | pub fn register_interrupt(self: Pin<&mut Self>) { | 113 | /// Registers `on_interrupt` as the wrapped interrupt's interrupt handler and enables it. |
| 118 | let this = unsafe { self.get_unchecked_mut() }; | 114 | /// |
| 115 | /// # Safety | ||
| 116 | /// The lifetime of any data in `PeripheralState` that is accessed by the interrupt handler | ||
| 117 | /// must not end without `Drop` being called on this `PeripheralMutex`. | ||
| 118 | /// | ||
| 119 | /// This can be accomplished by either not accessing any data with a lifetime in `on_interrupt`, | ||
| 120 | /// or making sure that nothing like `mem::forget` is used on the `PeripheralMutex`. | ||
| 121 | |||
| 122 | // TODO: this name isn't the best. | ||
| 123 | pub unsafe fn register_interrupt_unchecked(self: Pin<&mut Self>) { | ||
| 124 | let this = self.get_unchecked_mut(); | ||
| 119 | if this.irq_setup_done { | 125 | if this.irq_setup_done { |
| 120 | return; | 126 | return; |
| 121 | } | 127 | } |
| @@ -172,7 +178,7 @@ impl<S: PeripheralStateUnchecked> PeripheralMutex<S> { | |||
| 172 | } | 178 | } |
| 173 | } | 179 | } |
| 174 | 180 | ||
| 175 | impl<S: PeripheralStateUnchecked> Drop for PeripheralMutex<S> { | 181 | impl<S: PeripheralState> Drop for PeripheralMutex<S> { |
| 176 | fn drop(&mut self) { | 182 | fn drop(&mut self) { |
| 177 | self.irq.disable(); | 183 | self.irq.disable(); |
| 178 | self.irq.remove_handler(); | 184 | self.irq.remove_handler(); |
diff --git a/embassy-extras/src/peripheral_shared.rs b/embassy-extras/src/peripheral_shared.rs index 788ac3f96..71d746341 100644 --- a/embassy-extras/src/peripheral_shared.rs +++ b/embassy-extras/src/peripheral_shared.rs | |||
| @@ -5,30 +5,19 @@ use embassy::interrupt::{Interrupt, InterruptExt}; | |||
| 5 | 5 | ||
| 6 | use crate::peripheral::can_be_preempted; | 6 | use crate::peripheral::can_be_preempted; |
| 7 | 7 | ||
| 8 | /// A version of `PeripheralState` without the `'static` bound, | ||
| 9 | /// for cases where the compiler can't statically make sure | ||
| 10 | /// that `on_interrupt` doesn't reference anything which might be invalidated. | ||
| 11 | /// | ||
| 12 | /// # Safety | ||
| 13 | /// When types implementing this trait are used with `Peripheral`, | ||
| 14 | /// no fields referenced by `on_interrupt`'s lifetimes must end without first calling `Drop` on the `Peripheral`. | ||
| 15 | pub unsafe trait PeripheralStateUnchecked: Sync { | ||
| 16 | type Interrupt: Interrupt; | ||
| 17 | fn on_interrupt(&self); | ||
| 18 | } | ||
| 19 | |||
| 20 | /// A type which can be used as state with `Peripheral`. | 8 | /// A type which can be used as state with `Peripheral`. |
| 21 | /// | 9 | /// |
| 22 | /// It needs to be `Sync` because references are shared between the 'thread' which owns the `Peripheral` and the interrupt. | 10 | /// It needs to be `Sync` because references are shared between the 'thread' which owns the `Peripheral` and the interrupt. |
| 23 | /// | 11 | /// |
| 24 | /// It also requires `'static`, because although `Pin` guarantees that the memory of the state won't be invalidated, | 12 | /// It also requires `'static` to be used safely with `Peripheral::register_interrupt`, |
| 13 | /// because although `Pin` guarantees that the memory of the state won't be invalidated, | ||
| 25 | /// it doesn't guarantee that the lifetime will last. | 14 | /// it doesn't guarantee that the lifetime will last. |
| 26 | pub trait PeripheralState: Sync + 'static { | 15 | pub trait PeripheralState: Sync { |
| 27 | type Interrupt: Interrupt; | 16 | type Interrupt: Interrupt; |
| 28 | fn on_interrupt(&self); | 17 | fn on_interrupt(&self); |
| 29 | } | 18 | } |
| 30 | 19 | ||
| 31 | pub struct Peripheral<S: PeripheralStateUnchecked> { | 20 | pub struct Peripheral<S: PeripheralState> { |
| 32 | state: S, | 21 | state: S, |
| 33 | 22 | ||
| 34 | irq_setup_done: bool, | 23 | irq_setup_done: bool, |
| @@ -38,7 +27,24 @@ pub struct Peripheral<S: PeripheralStateUnchecked> { | |||
| 38 | _pinned: PhantomPinned, | 27 | _pinned: PhantomPinned, |
| 39 | } | 28 | } |
| 40 | 29 | ||
| 41 | impl<S: PeripheralStateUnchecked> Peripheral<S> { | 30 | impl<S: PeripheralState + 'static> Peripheral<S> { |
| 31 | /// Registers `on_interrupt` as the wrapped interrupt's interrupt handler and enables it. | ||
| 32 | /// | ||
| 33 | /// This requires this `Peripheral`'s `PeripheralState` to live for `'static`, | ||
| 34 | /// because `Pin` only guarantees that it's memory won't be repurposed, | ||
| 35 | /// not that it's lifetime will last. | ||
| 36 | /// | ||
| 37 | /// To use non-`'static` `PeripheralState`, use the unsafe `register_interrupt_unchecked`. | ||
| 38 | /// | ||
| 39 | /// Note: `'static` doesn't mean it _has_ to live for the entire program, like an `&'static T`; | ||
| 40 | /// it just means it _can_ live for the entire program - for example, `u8` lives for `'static`. | ||
| 41 | pub fn register_interrupt(self: Pin<&mut Self>) { | ||
| 42 | // SAFETY: `S: 'static`, so there's no way it's lifetime can expire. | ||
| 43 | unsafe { self.register_interrupt_unchecked() } | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | impl<S: PeripheralState> Peripheral<S> { | ||
| 42 | pub fn new(irq: S::Interrupt, state: S) -> Self { | 48 | pub fn new(irq: S::Interrupt, state: S) -> Self { |
| 43 | if can_be_preempted(&irq) { | 49 | if can_be_preempted(&irq) { |
| 44 | panic!("`Peripheral` cannot be created in an interrupt with higher priority than the interrupt it wraps"); | 50 | panic!("`Peripheral` cannot be created in an interrupt with higher priority than the interrupt it wraps"); |
| @@ -54,8 +60,16 @@ impl<S: PeripheralStateUnchecked> Peripheral<S> { | |||
| 54 | } | 60 | } |
| 55 | } | 61 | } |
| 56 | 62 | ||
| 57 | pub fn register_interrupt(self: Pin<&mut Self>) { | 63 | /// Registers `on_interrupt` as the wrapped interrupt's interrupt handler and enables it. |
| 58 | let this = unsafe { self.get_unchecked_mut() }; | 64 | /// |
| 65 | /// # Safety | ||
| 66 | /// The lifetime of any data in `PeripheralState` that is accessed by the interrupt handler | ||
| 67 | /// must not end without `Drop` being called on this `Peripheral`. | ||
| 68 | /// | ||
| 69 | /// This can be accomplished by either not accessing any data with a lifetime in `on_interrupt`, | ||
| 70 | /// or making sure that nothing like `mem::forget` is used on the `Peripheral`. | ||
| 71 | pub unsafe fn register_interrupt_unchecked(self: Pin<&mut Self>) { | ||
| 72 | let this = self.get_unchecked_mut(); | ||
| 59 | if this.irq_setup_done { | 73 | if this.irq_setup_done { |
| 60 | return; | 74 | return; |
| 61 | } | 75 | } |
| @@ -100,7 +114,7 @@ impl<S: PeripheralStateUnchecked> Peripheral<S> { | |||
| 100 | } | 114 | } |
| 101 | } | 115 | } |
| 102 | 116 | ||
| 103 | impl<S: PeripheralStateUnchecked> Drop for Peripheral<S> { | 117 | impl<S: PeripheralState> Drop for Peripheral<S> { |
| 104 | fn drop(&mut self) { | 118 | fn drop(&mut self) { |
| 105 | self.irq.disable(); | 119 | self.irq.disable(); |
| 106 | self.irq.remove_handler(); | 120 | self.irq.remove_handler(); |
diff --git a/embassy-extras/src/usb/mod.rs b/embassy-extras/src/usb/mod.rs index 481987a6c..1fb501d7f 100644 --- a/embassy-extras/src/usb/mod.rs +++ b/embassy-extras/src/usb/mod.rs | |||
| @@ -9,7 +9,7 @@ use usb_device::device::UsbDevice; | |||
| 9 | mod cdc_acm; | 9 | mod cdc_acm; |
| 10 | pub mod usb_serial; | 10 | pub mod usb_serial; |
| 11 | 11 | ||
| 12 | use crate::peripheral::{PeripheralMutex, PeripheralStateUnchecked}; | 12 | use crate::peripheral::{PeripheralMutex, PeripheralState}; |
| 13 | use embassy::interrupt::Interrupt; | 13 | use embassy::interrupt::Interrupt; |
| 14 | use usb_serial::{ReadInterface, UsbSerial, WriteInterface}; | 14 | use usb_serial::{ReadInterface, UsbSerial, WriteInterface}; |
| 15 | 15 | ||
| @@ -63,7 +63,9 @@ where | |||
| 63 | let mutex = Pin::new_unchecked(&mut *mutex); | 63 | let mutex = Pin::new_unchecked(&mut *mutex); |
| 64 | 64 | ||
| 65 | // Use inner to register the irq | 65 | // Use inner to register the irq |
| 66 | mutex.register_interrupt(); | 66 | // SAFETY: the safety contract of this function makes sure the `UsbDevice` won't be invalidated |
| 67 | // without the `PeripheralMutex` being dropped. | ||
| 68 | mutex.register_interrupt_unchecked(); | ||
| 67 | } | 69 | } |
| 68 | } | 70 | } |
| 69 | 71 | ||
| @@ -127,8 +129,7 @@ where | |||
| 127 | } | 129 | } |
| 128 | } | 130 | } |
| 129 | 131 | ||
| 130 | // SAFETY: The safety contract of `PeripheralStateUnchecked` is forwarded to `Usb::start`. | 132 | impl<'bus, B, T, I> PeripheralState for State<'bus, B, T, I> |
| 131 | unsafe impl<'bus, B, T, I> PeripheralStateUnchecked for State<'bus, B, T, I> | ||
| 132 | where | 133 | where |
| 133 | B: UsbBus, | 134 | B: UsbBus, |
| 134 | T: ClassSet<B>, | 135 | T: ClassSet<B>, |
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs index 2cce122bc..9be4d4d54 100644 --- a/embassy-nrf/src/buffered_uarte.rs +++ b/embassy-nrf/src/buffered_uarte.rs | |||
| @@ -7,7 +7,7 @@ use core::task::{Context, Poll}; | |||
| 7 | use embassy::interrupt::InterruptExt; | 7 | use embassy::interrupt::InterruptExt; |
| 8 | use embassy::io::{AsyncBufRead, AsyncWrite, Result}; | 8 | use embassy::io::{AsyncBufRead, AsyncWrite, Result}; |
| 9 | use embassy::util::{Unborrow, WakerRegistration}; | 9 | use embassy::util::{Unborrow, WakerRegistration}; |
| 10 | use embassy_extras::peripheral::{PeripheralMutex, PeripheralStateUnchecked}; | 10 | use embassy_extras::peripheral::{PeripheralMutex, PeripheralState}; |
| 11 | use embassy_extras::ring_buffer::RingBuffer; | 11 | use embassy_extras::ring_buffer::RingBuffer; |
| 12 | use embassy_extras::{low_power_wait_until, unborrow}; | 12 | use embassy_extras::{low_power_wait_until, unborrow}; |
| 13 | 13 | ||
| @@ -175,7 +175,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 175 | 175 | ||
| 176 | pub fn set_baudrate(self: Pin<&mut Self>, baudrate: Baudrate) { | 176 | pub fn set_baudrate(self: Pin<&mut Self>, baudrate: Baudrate) { |
| 177 | let mut inner = self.inner(); | 177 | let mut inner = self.inner(); |
| 178 | inner.as_mut().register_interrupt(); | 178 | unsafe { inner.as_mut().register_interrupt_unchecked() } |
| 179 | inner.with(|state| { | 179 | inner.with(|state| { |
| 180 | let r = U::regs(); | 180 | let r = U::regs(); |
| 181 | 181 | ||
| @@ -195,7 +195,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> BufferedUarte<'d, U, T> { | |||
| 195 | impl<'d, U: UarteInstance, T: TimerInstance> AsyncBufRead for BufferedUarte<'d, U, T> { | 195 | impl<'d, U: UarteInstance, T: TimerInstance> AsyncBufRead for BufferedUarte<'d, U, T> { |
| 196 | fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>> { | 196 | fn poll_fill_buf(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<&[u8]>> { |
| 197 | let mut inner = self.inner(); | 197 | let mut inner = self.inner(); |
| 198 | inner.as_mut().register_interrupt(); | 198 | unsafe { inner.as_mut().register_interrupt_unchecked() } |
| 199 | inner.with(|state| { | 199 | inner.with(|state| { |
| 200 | // Conservative compiler fence to prevent optimizations that do not | 200 | // Conservative compiler fence to prevent optimizations that do not |
| 201 | // take in to account actions by DMA. The fence has been placed here, | 201 | // take in to account actions by DMA. The fence has been placed here, |
| @@ -220,7 +220,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> AsyncBufRead for BufferedUarte<'d, | |||
| 220 | 220 | ||
| 221 | fn consume(self: Pin<&mut Self>, amt: usize) { | 221 | fn consume(self: Pin<&mut Self>, amt: usize) { |
| 222 | let mut inner = self.inner(); | 222 | let mut inner = self.inner(); |
| 223 | inner.as_mut().register_interrupt(); | 223 | unsafe { inner.as_mut().register_interrupt_unchecked() } |
| 224 | inner.as_mut().with(|state| { | 224 | inner.as_mut().with(|state| { |
| 225 | trace!("consume {:?}", amt); | 225 | trace!("consume {:?}", amt); |
| 226 | state.rx.pop(amt); | 226 | state.rx.pop(amt); |
| @@ -232,7 +232,7 @@ impl<'d, U: UarteInstance, T: TimerInstance> AsyncBufRead for BufferedUarte<'d, | |||
| 232 | impl<'d, U: UarteInstance, T: TimerInstance> AsyncWrite for BufferedUarte<'d, U, T> { | 232 | impl<'d, U: UarteInstance, T: TimerInstance> AsyncWrite for BufferedUarte<'d, U, T> { |
| 233 | fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize>> { | 233 | fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize>> { |
| 234 | let mut inner = self.inner(); | 234 | let mut inner = self.inner(); |
| 235 | inner.as_mut().register_interrupt(); | 235 | unsafe { inner.as_mut().register_interrupt_unchecked() } |
| 236 | let poll = inner.as_mut().with(|state| { | 236 | let poll = inner.as_mut().with(|state| { |
| 237 | trace!("poll_write: {:?}", buf.len()); | 237 | trace!("poll_write: {:?}", buf.len()); |
| 238 | 238 | ||
| @@ -285,8 +285,7 @@ impl<'a, U: UarteInstance, T: TimerInstance> Drop for State<'a, U, T> { | |||
| 285 | } | 285 | } |
| 286 | } | 286 | } |
| 287 | 287 | ||
| 288 | // SAFETY: the safety contract of `PeripheralStateUnchecked` is forwarded to `BufferedUarte::new`. | 288 | impl<'a, U: UarteInstance, T: TimerInstance> PeripheralState for State<'a, U, T> { |
| 289 | unsafe impl<'a, U: UarteInstance, T: TimerInstance> PeripheralStateUnchecked for State<'a, U, T> { | ||
| 290 | type Interrupt = U::Interrupt; | 289 | type Interrupt = U::Interrupt; |
| 291 | fn on_interrupt(&mut self) { | 290 | fn on_interrupt(&mut self) { |
| 292 | trace!("irq: start"); | 291 | trace!("irq: start"); |
diff --git a/embassy-stm32/src/eth/v2/mod.rs b/embassy-stm32/src/eth/v2/mod.rs index 3ac09f944..129d2d02c 100644 --- a/embassy-stm32/src/eth/v2/mod.rs +++ b/embassy-stm32/src/eth/v2/mod.rs | |||
| @@ -4,7 +4,7 @@ use core::sync::atomic::{fence, Ordering}; | |||
| 4 | use core::task::Waker; | 4 | use core::task::Waker; |
| 5 | 5 | ||
| 6 | use embassy::util::{AtomicWaker, Unborrow}; | 6 | use embassy::util::{AtomicWaker, Unborrow}; |
| 7 | use embassy_extras::peripheral::{PeripheralMutex, PeripheralStateUnchecked}; | 7 | use embassy_extras::peripheral::{PeripheralMutex, PeripheralState}; |
| 8 | use embassy_extras::unborrow; | 8 | use embassy_extras::unborrow; |
| 9 | use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU}; | 9 | use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU}; |
| 10 | 10 | ||
| @@ -159,7 +159,8 @@ impl<'d, P: PHY, const TX: usize, const RX: usize> Ethernet<'d, P, TX, RX> { | |||
| 159 | // NOTE(unsafe) We won't move this | 159 | // NOTE(unsafe) We won't move this |
| 160 | let this = unsafe { self.get_unchecked_mut() }; | 160 | let this = unsafe { self.get_unchecked_mut() }; |
| 161 | let mut mutex = unsafe { Pin::new_unchecked(&mut this.state) }; | 161 | let mut mutex = unsafe { Pin::new_unchecked(&mut this.state) }; |
| 162 | mutex.as_mut().register_interrupt(); | 162 | // SAFETY: The lifetime of `Inner` is only due to `PhantomData`; it isn't actually referencing any data with that lifetime. |
| 163 | unsafe { mutex.as_mut().register_interrupt_unchecked() } | ||
| 163 | 164 | ||
| 164 | mutex.with(|s| { | 165 | mutex.with(|s| { |
| 165 | s.desc_ring.init(); | 166 | s.desc_ring.init(); |
| @@ -343,8 +344,7 @@ impl<'d, const TX: usize, const RX: usize> Inner<'d, TX, RX> { | |||
| 343 | } | 344 | } |
| 344 | } | 345 | } |
| 345 | 346 | ||
| 346 | // SAFETY: The lifetime of `Inner` is only due to `PhantomData`; it isn't actually referencing any data with that lifetime. | 347 | impl<'d, const TX: usize, const RX: usize> PeripheralState for Inner<'d, TX, RX> { |
| 347 | unsafe impl<'d, const TX: usize, const RX: usize> PeripheralStateUnchecked for Inner<'d, TX, RX> { | ||
| 348 | type Interrupt = crate::interrupt::ETH; | 348 | type Interrupt = crate::interrupt::ETH; |
| 349 | 349 | ||
| 350 | fn on_interrupt(&mut self) { | 350 | fn on_interrupt(&mut self) { |
