aboutsummaryrefslogtreecommitdiff
path: root/embassy-nrf/src
diff options
context:
space:
mode:
authorLiam Murphy <[email protected]>2021-07-05 17:42:43 +1000
committerLiam Murphy <[email protected]>2021-07-05 17:42:43 +1000
commit744e2cbb8a0b58eccf3a9708c8c28f1ef17e4771 (patch)
treee288df991575c86e5079bdb33b7c1fd7888e96cb /embassy-nrf/src
parented83b93b6dd34cf09d1f772ec32ebd036e8798a7 (diff)
extras: Fix UB in `Peripheral`
`Peripheral` assumed that interrupts can't be preempted, when they can be preempted by higher priority interrupts. So I put the interrupt handler inside a critical section, and also added checks for whether the state had been dropped before the critical section was entered. I also added a `'static` bound to `PeripheralState`, since `Pin` only guarantees that the memory it directly references will not be invalidated. It doesn't guarantee that memory its pointee references also won't be invalidated. There were already some implementations of `PeripheralState` that weren't `'static`, though, so I added an unsafe `PeripheralStateUnchecked` trait and forwarded the `unsafe` to the constructors of the implementors.
Diffstat (limited to 'embassy-nrf/src')
-rw-r--r--embassy-nrf/src/buffered_uarte.rs5
1 files changed, 3 insertions, 2 deletions
diff --git a/embassy-nrf/src/buffered_uarte.rs b/embassy-nrf/src/buffered_uarte.rs
index a5a37b982..1fa98a6b2 100644
--- a/embassy-nrf/src/buffered_uarte.rs
+++ b/embassy-nrf/src/buffered_uarte.rs
@@ -7,7 +7,7 @@ use core::task::{Context, Poll};
7use embassy::interrupt::InterruptExt; 7use embassy::interrupt::InterruptExt;
8use embassy::io::{AsyncBufRead, AsyncWrite, Result}; 8use embassy::io::{AsyncBufRead, AsyncWrite, Result};
9use embassy::util::{Unborrow, WakerRegistration}; 9use embassy::util::{Unborrow, WakerRegistration};
10use embassy_extras::peripheral::{PeripheralMutex, PeripheralState}; 10use embassy_extras::peripheral::{PeripheralMutex, PeripheralStateUnchecked};
11use embassy_extras::ring_buffer::RingBuffer; 11use embassy_extras::ring_buffer::RingBuffer;
12use embassy_extras::{low_power_wait_until, unborrow}; 12use embassy_extras::{low_power_wait_until, unborrow};
13 13
@@ -283,7 +283,8 @@ impl<'a, U: UarteInstance, T: TimerInstance> Drop for State<'a, U, T> {
283 } 283 }
284} 284}
285 285
286impl<'a, U: UarteInstance, T: TimerInstance> PeripheralState for State<'a, U, T> { 286// SAFETY: the safety contract of `PeripheralStateUnchecked` is forwarded to `BufferedUarte::new`.
287unsafe impl<'a, U: UarteInstance, T: TimerInstance> PeripheralStateUnchecked for State<'a, U, T> {
287 type Interrupt = U::Interrupt; 288 type Interrupt = U::Interrupt;
288 fn on_interrupt(&mut self) { 289 fn on_interrupt(&mut self) {
289 trace!("irq: start"); 290 trace!("irq: start");