diff options
| author | Dario Nieuwenhuis <[email protected]> | 2021-08-02 20:13:41 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2021-08-02 20:13:41 +0200 |
| commit | 3f28bb6c77de3d8ecbb6d401f107586f24e416a4 (patch) | |
| tree | da16008285a54746a07bdf7881a4fce4cbf8d23e /embassy-hal-common | |
| parent | e238079d7d921cab589eb6106059d4fb0b12ce1c (diff) | |
common: Initialize PeripheralMutex state with closure to ensure it's done in-place.
Diffstat (limited to 'embassy-hal-common')
| -rw-r--r-- | embassy-hal-common/src/peripheral.rs | 18 | ||||
| -rw-r--r-- | embassy-hal-common/src/usb/mod.rs | 5 |
2 files changed, 13 insertions, 10 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 | } |
