diff options
| author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2022-07-23 13:15:17 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2022-07-23 13:15:17 +0000 |
| commit | e61e36a8158073ec92df1a751cfdd7fce5004cf8 (patch) | |
| tree | 4a54aee47c0d3881b9e0bc809e075728cee8eeae /embassy-cortex-m | |
| parent | 96f67671677d8bf7175f98e87c98954dc728286c (diff) | |
| parent | 709df0dc1dfff577fb79bbc2f67ea84670072456 (diff) | |
Merge #842
842: WIP: Make unborrow safe to use r=Dirbaio a=GrantM11235
The basic idea is that `Unborrow::unborrow` is now safe to call and returns an `Unborrowed<'a, T>` which impls `Deref` and `DerefMut`
```rust
/// This is essentially a `&mut T`, but it is the size of `T` not the size
/// of a pointer. This is useful if T is a zero sized type.
pub struct Unborrowed<'a, T> {
inner: T,
_lifetime: PhantomData<&'a mut T>,
}
```
## Todo
- [x] Update other crates
- [x] embassy-cortex-m
- [x] embassy-hal-common
- [x] embassy-lora
- [x] embassy-nrf
- [x] embassy-rp
- [x] embassy-stm32
- [x] Remove usage of the unsafe `into_inner` method if possible
- [x] Review and amend docs for `Unborrow` and `Unborrowed`
Co-authored-by: Grant Miller <[email protected]>
Co-authored-by: Dario Nieuwenhuis <[email protected]>
Diffstat (limited to 'embassy-cortex-m')
| -rw-r--r-- | embassy-cortex-m/src/interrupt.rs | 4 | ||||
| -rw-r--r-- | embassy-cortex-m/src/peripheral.rs | 21 |
2 files changed, 13 insertions, 12 deletions
diff --git a/embassy-cortex-m/src/interrupt.rs b/embassy-cortex-m/src/interrupt.rs index 715f00381..7358caa46 100644 --- a/embassy-cortex-m/src/interrupt.rs +++ b/embassy-cortex-m/src/interrupt.rs | |||
| @@ -3,7 +3,7 @@ use core::{mem, ptr}; | |||
| 3 | 3 | ||
| 4 | use atomic_polyfill::{compiler_fence, AtomicPtr, Ordering}; | 4 | use atomic_polyfill::{compiler_fence, AtomicPtr, Ordering}; |
| 5 | use cortex_m::peripheral::NVIC; | 5 | use cortex_m::peripheral::NVIC; |
| 6 | use embassy_hal_common::Unborrow; | 6 | use embassy_hal_common::Peripheral; |
| 7 | pub use embassy_macros::cortex_m_interrupt_take as take; | 7 | pub use embassy_macros::cortex_m_interrupt_take as take; |
| 8 | 8 | ||
| 9 | /// Implementation detail, do not use outside embassy crates. | 9 | /// Implementation detail, do not use outside embassy crates. |
| @@ -32,7 +32,7 @@ unsafe impl cortex_m::interrupt::InterruptNumber for NrWrap { | |||
| 32 | 32 | ||
| 33 | /// Represents an interrupt type that can be configured by embassy to handle | 33 | /// Represents an interrupt type that can be configured by embassy to handle |
| 34 | /// interrupts. | 34 | /// interrupts. |
| 35 | pub unsafe trait Interrupt: Unborrow<Target = Self> { | 35 | pub unsafe trait Interrupt: Peripheral<P = Self> { |
| 36 | /// Return the NVIC interrupt number for this interrupt. | 36 | /// Return the NVIC interrupt number for this interrupt. |
| 37 | fn number(&self) -> u16; | 37 | fn number(&self) -> u16; |
| 38 | /// Steal an instance of this interrupt | 38 | /// Steal an instance of this interrupt |
diff --git a/embassy-cortex-m/src/peripheral.rs b/embassy-cortex-m/src/peripheral.rs index 6a03bfb9f..e2f295579 100644 --- a/embassy-cortex-m/src/peripheral.rs +++ b/embassy-cortex-m/src/peripheral.rs | |||
| @@ -1,9 +1,9 @@ | |||
| 1 | //! Peripheral interrupt handling specific to cortex-m devices. | 1 | //! Peripheral interrupt handling specific to cortex-m devices. |
| 2 | use core::marker::PhantomData; | ||
| 3 | use core::mem::MaybeUninit; | 2 | use core::mem::MaybeUninit; |
| 4 | 3 | ||
| 5 | use cortex_m::peripheral::scb::VectActive; | 4 | use cortex_m::peripheral::scb::VectActive; |
| 6 | use cortex_m::peripheral::{NVIC, SCB}; | 5 | use cortex_m::peripheral::{NVIC, SCB}; |
| 6 | use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; | ||
| 7 | 7 | ||
| 8 | use crate::interrupt::{Interrupt, InterruptExt, Priority}; | 8 | use crate::interrupt::{Interrupt, InterruptExt, Priority}; |
| 9 | 9 | ||
| @@ -33,8 +33,7 @@ impl<S> StateStorage<S> { | |||
| 33 | /// a safe way. | 33 | /// a safe way. |
| 34 | pub struct PeripheralMutex<'a, S: PeripheralState> { | 34 | pub struct PeripheralMutex<'a, S: PeripheralState> { |
| 35 | state: *mut S, | 35 | state: *mut S, |
| 36 | _phantom: PhantomData<&'a mut S>, | 36 | irq: PeripheralRef<'a, S::Interrupt>, |
| 37 | irq: S::Interrupt, | ||
| 38 | } | 37 | } |
| 39 | 38 | ||
| 40 | /// Whether `irq` can be preempted by the current interrupt. | 39 | /// Whether `irq` can be preempted by the current interrupt. |
| @@ -62,8 +61,14 @@ impl<'a, S: PeripheralState> PeripheralMutex<'a, S> { | |||
| 62 | /// Create a new `PeripheralMutex` wrapping `irq`, with `init` initializing the initial state. | 61 | /// Create a new `PeripheralMutex` wrapping `irq`, with `init` initializing the initial state. |
| 63 | /// | 62 | /// |
| 64 | /// Registers `on_interrupt` as the `irq`'s handler, and enables it. | 63 | /// Registers `on_interrupt` as the `irq`'s handler, and enables it. |
| 65 | pub fn new(irq: S::Interrupt, storage: &'a mut StateStorage<S>, init: impl FnOnce() -> S) -> Self { | 64 | pub fn new( |
| 66 | if can_be_preempted(&irq) { | 65 | irq: impl Peripheral<P = S::Interrupt> + 'a, |
| 66 | storage: &'a mut StateStorage<S>, | ||
| 67 | init: impl FnOnce() -> S, | ||
| 68 | ) -> Self { | ||
| 69 | into_ref!(irq); | ||
| 70 | |||
| 71 | if can_be_preempted(&*irq) { | ||
| 67 | panic!( | 72 | panic!( |
| 68 | "`PeripheralMutex` cannot be created in an interrupt with higher priority than the interrupt it wraps" | 73 | "`PeripheralMutex` cannot be created in an interrupt with higher priority than the interrupt it wraps" |
| 69 | ); | 74 | ); |
| @@ -88,11 +93,7 @@ impl<'a, S: PeripheralState> PeripheralMutex<'a, S> { | |||
| 88 | irq.set_handler_context(state_ptr as *mut ()); | 93 | irq.set_handler_context(state_ptr as *mut ()); |
| 89 | irq.enable(); | 94 | irq.enable(); |
| 90 | 95 | ||
| 91 | Self { | 96 | Self { irq, state: state_ptr } |
| 92 | irq, | ||
| 93 | state: state_ptr, | ||
| 94 | _phantom: PhantomData, | ||
| 95 | } | ||
| 96 | } | 97 | } |
| 97 | 98 | ||
| 98 | /// Access the peripheral state ensuring interrupts are disabled so that the state can be | 99 | /// Access the peripheral state ensuring interrupts are disabled so that the state can be |
