From 72109a7bda5cf1568b1ff2b1b4b7de06f73d3342 Mon Sep 17 00:00:00 2001 From: Kenneth Knudsen Date: Wed, 6 Nov 2024 10:52:03 +0100 Subject: [PATCH] Split_ref with shortened lifetime. When borrowed skip drop on rx and tx --- embassy-stm32/src/usart/buffered.rs | 78 +++++++++++++++++++---------- 1 file changed, 52 insertions(+), 26 deletions(-) diff --git a/embassy-stm32/src/usart/buffered.rs b/embassy-stm32/src/usart/buffered.rs index d7ac33d07..f7b2bf4b4 100644 --- a/embassy-stm32/src/usart/buffered.rs +++ b/embassy-stm32/src/usart/buffered.rs @@ -157,6 +157,7 @@ pub struct BufferedUartTx<'d> { tx: Option>, cts: Option>, de: Option>, + is_borrowed: bool, } /// Rx-only buffered UART @@ -168,6 +169,7 @@ pub struct BufferedUartRx<'d> { kernel_clock: Hertz, rx: Option>, rts: Option>, + is_borrowed: bool, } impl<'d> SetConfig for BufferedUart<'d> { @@ -341,6 +343,7 @@ impl<'d> BufferedUart<'d> { kernel_clock, rx, rts, + is_borrowed: false, }, tx: BufferedUartTx { info, @@ -349,6 +352,7 @@ impl<'d> BufferedUart<'d> { tx, cts, de, + is_borrowed: false, }, }; this.enable_and_configure(tx_buffer, rx_buffer, &config)?; @@ -396,11 +400,29 @@ impl<'d> BufferedUart<'d> { (self.tx, self.rx) } - /// Split the Uart into a transmitter and receiver by mutable reference, + /// Split the Uart into a transmitter and receiver, /// which is particularly useful when having two tasks correlating to /// transmitting and receiving. - pub fn split_ref(&mut self) -> (&mut BufferedUartTx<'d>, &mut BufferedUartRx<'d>) { - (&mut self.tx, &mut self.rx) + pub fn split_ref(&mut self) -> (BufferedUartTx<'_>, BufferedUartRx<'_>) { + ( + BufferedUartTx { + info: self.tx.info, + state: self.tx.state, + kernel_clock: self.tx.kernel_clock, + tx: self.tx.tx.as_mut().map(PeripheralRef::reborrow), + cts: self.tx.cts.as_mut().map(PeripheralRef::reborrow), + de: self.tx.de.as_mut().map(PeripheralRef::reborrow), + is_borrowed: true, + }, + BufferedUartRx { + info: self.rx.info, + state: self.rx.state, + kernel_clock: self.rx.kernel_clock, + rx: self.rx.rx.as_mut().map(PeripheralRef::reborrow), + rts: self.rx.rts.as_mut().map(PeripheralRef::reborrow), + is_borrowed: true, + }, + ) } /// Reconfigure the driver @@ -607,40 +629,44 @@ impl<'d> BufferedUartTx<'d> { impl<'d> Drop for BufferedUartRx<'d> { fn drop(&mut self) { - let state = self.state; - unsafe { - state.rx_buf.deinit(); + if !self.is_borrowed { + let state = self.state; + unsafe { + state.rx_buf.deinit(); - // TX is inactive if the the buffer is not available. - // We can now unregister the interrupt handler - if state.tx_buf.len() == 0 { - self.info.interrupt.disable(); + // TX is inactive if the the buffer is not available. + // We can now unregister the interrupt handler + if state.tx_buf.len() == 0 { + self.info.interrupt.disable(); + } } - } - self.rx.as_ref().map(|x| x.set_as_disconnected()); - self.rts.as_ref().map(|x| x.set_as_disconnected()); - drop_tx_rx(self.info, state); + self.rx.as_ref().map(|x| x.set_as_disconnected()); + self.rts.as_ref().map(|x| x.set_as_disconnected()); + drop_tx_rx(self.info, state); + } } } impl<'d> Drop for BufferedUartTx<'d> { fn drop(&mut self) { - let state = self.state; - unsafe { - state.tx_buf.deinit(); + if !self.is_borrowed { + let state = self.state; + unsafe { + state.tx_buf.deinit(); - // RX is inactive if the the buffer is not available. - // We can now unregister the interrupt handler - if state.rx_buf.len() == 0 { - self.info.interrupt.disable(); + // RX is inactive if the the buffer is not available. + // We can now unregister the interrupt handler + if state.rx_buf.len() == 0 { + self.info.interrupt.disable(); + } } - } - self.tx.as_ref().map(|x| x.set_as_disconnected()); - self.cts.as_ref().map(|x| x.set_as_disconnected()); - self.de.as_ref().map(|x| x.set_as_disconnected()); - drop_tx_rx(self.info, state); + self.tx.as_ref().map(|x| x.set_as_disconnected()); + self.cts.as_ref().map(|x| x.set_as_disconnected()); + self.de.as_ref().map(|x| x.set_as_disconnected()); + drop_tx_rx(self.info, state); + } } }