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.
This commit is contained in:
@ -7,7 +7,7 @@ use core::task::{Context, Poll};
|
||||
use embassy::interrupt::InterruptExt;
|
||||
use embassy::io::{AsyncBufRead, AsyncWrite, Result};
|
||||
use embassy::util::{Unborrow, WakerRegistration};
|
||||
use embassy_extras::peripheral::{PeripheralMutex, PeripheralState};
|
||||
use embassy_extras::peripheral::{PeripheralMutex, PeripheralStateUnchecked};
|
||||
use embassy_extras::ring_buffer::RingBuffer;
|
||||
use embassy_extras::{low_power_wait_until, unborrow};
|
||||
|
||||
@ -283,7 +283,8 @@ impl<'a, U: UarteInstance, T: TimerInstance> Drop for State<'a, U, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, U: UarteInstance, T: TimerInstance> PeripheralState for State<'a, U, T> {
|
||||
// SAFETY: the safety contract of `PeripheralStateUnchecked` is forwarded to `BufferedUarte::new`.
|
||||
unsafe impl<'a, U: UarteInstance, T: TimerInstance> PeripheralStateUnchecked for State<'a, U, T> {
|
||||
type Interrupt = U::Interrupt;
|
||||
fn on_interrupt(&mut self) {
|
||||
trace!("irq: start");
|
||||
|
Reference in New Issue
Block a user