Skip to content

Commit ae2c57c

Browse files
committed
Replace use of Pin with StableDeref bounds
Using Pin for DMA buffers does not provide the necessary safety. See rust-embedded/embedonomicon#64
1 parent e9d7a38 commit ae2c57c

File tree

4 files changed

+24
-25
lines changed

4 files changed

+24
-25
lines changed

Cargo.toml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,21 @@ version = "0.2"
3131
features = ["const-fn"]
3232

3333
[dependencies.cast]
34-
default-features = false
3534
version = "0.2"
36-
37-
[dependencies.void]
3835
default-features = false
36+
37+
[dependencies.stable_deref_trait]
3938
version = "1"
39+
default-features = false
4040

4141
[dependencies.stm32-usbd]
4242
version = "0.5"
4343
optional = true
4444

45+
[dependencies.void]
46+
version = "1"
47+
default-features = false
48+
4549
[dev-dependencies]
4650
panic-semihosting = "0.5"
4751
usb-device = "0.2"

examples/serial_dma.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
use panic_semihosting as _;
99

10-
use core::pin::Pin;
1110
use cortex_m::singleton;
1211
use cortex_m_rt::entry;
1312
use stm32f3xx_hal::{prelude::*, serial::Serial, stm32};
@@ -43,11 +42,11 @@ fn main() -> ! {
4342
let (tx_channel, rx_channel) = (dma1.ch4, dma1.ch5);
4443

4544
// start separate DMAs for sending and receiving the data
46-
let sending = tx.write_all(Pin::new(tx_buf), tx_channel);
47-
let receiving = rx.read_exact(Pin::new(rx_buf), rx_channel);
45+
let sending = tx.write_all(tx_buf, tx_channel);
46+
let receiving = rx.read_exact(rx_buf, rx_channel);
4847

4948
// block until all data was transmitted and received
50-
let (mut tx_buf, tx_channel, tx) = sending.wait();
49+
let (tx_buf, tx_channel, tx) = sending.wait();
5150
let (rx_buf, rx_channel, rx) = receiving.wait();
5251

5352
assert_eq!(tx_buf, rx_buf);

src/dma.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,8 @@ use crate::{
1010
stm32::{self, dma1::ch::cr},
1111
};
1212
use cast::u16;
13-
use core::{
14-
pin::Pin,
15-
sync::atomic::{self, Ordering},
16-
};
13+
use core::sync::atomic::{self, Ordering};
14+
use stable_deref_trait::StableDeref;
1715

1816
/// Extension trait to split a DMA peripheral into independent channels
1917
pub trait DmaExt {
@@ -37,9 +35,9 @@ impl<B, C: Channel, T> Transfer<B, C, T> {
3735
///
3836
/// Callers must ensure that the DMA channel is configured correctly for
3937
/// the given target and buffer.
40-
pub unsafe fn start(buffer: Pin<B>, mut channel: C, target: T) -> Self
38+
pub unsafe fn start(buffer: B, mut channel: C, target: T) -> Self
4139
where
42-
B: 'static,
40+
B: StableDeref + 'static,
4341
T: Target<C>,
4442
{
4543
assert!(!channel.is_enabled());
@@ -64,15 +62,15 @@ impl<B, C: Channel, T> Transfer<B, C, T> {
6462
}
6563

6664
/// Stop this transfer and return ownership over its parts
67-
pub fn stop(mut self) -> (Pin<B>, C, T) {
65+
pub fn stop(mut self) -> (B, C, T) {
6866
let mut inner = self.inner.take().unwrap();
6967
inner.stop();
7068

7169
(inner.buffer, inner.channel, inner.target)
7270
}
7371

7472
/// Block until this transfer is done and return ownership over its parts
75-
pub fn wait(self) -> (Pin<B>, C, T) {
73+
pub fn wait(self) -> (B, C, T) {
7674
while !self.is_complete() {}
7775

7876
self.stop()
@@ -89,7 +87,7 @@ impl<B, C: Channel, T> Drop for Transfer<B, C, T> {
8987

9088
/// This only exists so we can implement `Drop` for `Transfer`.
9189
struct TransferInner<B, C, T> {
92-
buffer: Pin<B>,
90+
buffer: B,
9391
channel: C,
9492
target: T,
9593
}

src/serial.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,8 @@ use crate::gpio::gpioe;
4242
mod dma_imports {
4343
pub use crate::dma;
4444
pub use as_slice::{AsMutSlice, AsSlice};
45-
pub use core::{
46-
ops::{Deref, DerefMut},
47-
pin::Pin,
48-
};
45+
pub use core::ops::{Deref, DerefMut};
46+
pub use stable_deref_trait::StableDeref;
4947
}
5048

5149
#[cfg(feature = "stm32f303")]
@@ -383,13 +381,13 @@ macro_rules! hal {
383381
/// Fill the buffer with received data using DMA.
384382
pub fn read_exact<B, C>(
385383
self,
386-
mut buffer: Pin<B>,
384+
mut buffer: B,
387385
mut channel: C
388386
) -> dma::Transfer<B, C, Self>
389387
where
390388
Self: dma::Target<C>,
391-
B: DerefMut + 'static,
392-
B::Target: AsMutSlice<Element = u8> + Unpin,
389+
B: DerefMut + StableDeref + 'static,
390+
B::Target: AsMutSlice<Element = u8>,
393391
C: dma::Channel,
394392
{
395393
// NOTE(unsafe) taking the address of a register
@@ -413,12 +411,12 @@ macro_rules! hal {
413411
/// Transmit all data in the buffer using DMA.
414412
pub fn write_all<B, C>(
415413
self,
416-
buffer: Pin<B>,
414+
buffer: B,
417415
mut channel: C
418416
) -> dma::Transfer<B, C, Self>
419417
where
420418
Self: dma::Target<C>,
421-
B: Deref + 'static,
419+
B: Deref + StableDeref + 'static,
422420
B::Target: AsSlice<Element = u8>,
423421
C: dma::Channel,
424422
{

0 commit comments

Comments
 (0)