From 95b31cf2db647b8d1779cc3f7439d5c7df98f379 Mon Sep 17 00:00:00 2001 From: Rasmus Melchior Jacobsen Date: Wed, 5 Apr 2023 10:27:13 +0200 Subject: [PATCH] Remove Drop on Flash and FlashLayout and propage lifetime to region types This allows the user to "split" the FlashRegions struct into each region --- embassy-stm32/build.rs | 11 ++++---- embassy-stm32/src/flash/common.rs | 20 +++------------ embassy-stm32/src/flash/f4.rs | 42 ++++++++++++++++--------------- 3 files changed, 31 insertions(+), 42 deletions(-) diff --git a/embassy-stm32/build.rs b/embassy-stm32/build.rs index 9df5a58d..61aceed9 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs @@ -148,7 +148,8 @@ fn main() { let region_type = format_ident!("{}", get_flash_region_type_name(region.name)); flash_regions.extend(quote! { - pub struct #region_type(pub &'static crate::flash::FlashRegion); + #[cfg(flash)] + pub struct #region_type<'d>(pub &'static crate::flash::FlashRegion, pub(crate) embassy_hal_common::PeripheralRef<'d, crate::peripherals::FLASH>,); }); } @@ -159,11 +160,11 @@ fn main() { let field_name = format_ident!("{}", region_name.to_lowercase()); let field_type = format_ident!("{}", get_flash_region_type_name(f.name)); let field = quote! { - pub #field_name: #field_type + pub #field_name: #field_type<'d> }; let region_name = format_ident!("{}", region_name); let init = quote! { - #field_name: #field_type(&#region_name) + #field_name: #field_type(&#region_name, unsafe { p.clone_unchecked()}) }; (field, (init, region_name)) @@ -174,15 +175,13 @@ fn main() { flash_regions.extend(quote! { #[cfg(flash)] pub struct FlashLayout<'d> { - _inner: embassy_hal_common::PeripheralRef<'d, crate::peripherals::FLASH>, #(#fields),* } #[cfg(flash)] impl<'d> FlashLayout<'d> { - pub(crate) const fn new(p: embassy_hal_common::PeripheralRef<'d, crate::peripherals::FLASH>) -> Self { + pub(crate) fn new(mut p: embassy_hal_common::PeripheralRef<'d, crate::peripherals::FLASH>) -> Self { Self { - _inner: p, #(#inits),* } } diff --git a/embassy-stm32/src/flash/common.rs b/embassy-stm32/src/flash/common.rs index c48b2f2e..8235d6f0 100644 --- a/embassy-stm32/src/flash/common.rs +++ b/embassy-stm32/src/flash/common.rs @@ -38,18 +38,6 @@ impl<'d> Flash<'d> { } } -impl Drop for Flash<'_> { - fn drop(&mut self) { - unsafe { family::lock() }; - } -} - -impl Drop for FlashLayout<'_> { - fn drop(&mut self) { - unsafe { family::lock() }; - } -} - fn blocking_read(base: u32, size: u32, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { if offset + bytes.len() as u32 > size { return Err(Error::Size); @@ -177,7 +165,7 @@ impl FlashRegion { foreach_flash_region! { ($type_name:ident, $write_size:literal, $erase_size:literal) => { - impl crate::_generated::flash_regions::$type_name { + impl crate::_generated::flash_regions::$type_name<'_> { pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { blocking_read(self.0.base, self.0.size, offset, bytes) } @@ -191,11 +179,11 @@ foreach_flash_region! { } } - impl embedded_storage::nor_flash::ErrorType for crate::_generated::flash_regions::$type_name { + impl embedded_storage::nor_flash::ErrorType for crate::_generated::flash_regions::$type_name<'_> { type Error = Error; } - impl embedded_storage::nor_flash::ReadNorFlash for crate::_generated::flash_regions::$type_name { + impl embedded_storage::nor_flash::ReadNorFlash for crate::_generated::flash_regions::$type_name<'_> { const READ_SIZE: usize = 1; fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> { @@ -207,7 +195,7 @@ foreach_flash_region! { } } - impl embedded_storage::nor_flash::NorFlash for crate::_generated::flash_regions::$type_name { + impl embedded_storage::nor_flash::NorFlash for crate::_generated::flash_regions::$type_name<'_> { const WRITE_SIZE: usize = $write_size; const ERASE_SIZE: usize = $erase_size; diff --git a/embassy-stm32/src/flash/f4.rs b/embassy-stm32/src/flash/f4.rs index 2f5b417c..2ce9df69 100644 --- a/embassy-stm32/src/flash/f4.rs +++ b/embassy-stm32/src/flash/f4.rs @@ -45,34 +45,36 @@ mod alt_regions { &ALT_BANK2_REGION3, ]; - pub type AltBank1Region1 = Bank1Region1; - pub type AltBank1Region2 = Bank1Region2; - pub struct AltBank1Region3(&'static FlashRegion); - pub struct AltBank2Region1(&'static FlashRegion); - pub struct AltBank2Region2(&'static FlashRegion); - pub struct AltBank2Region3(&'static FlashRegion); + pub type AltBank1Region1<'d> = Bank1Region1<'d>; + pub type AltBank1Region2<'d> = Bank1Region2<'d>; + pub struct AltBank1Region3<'d>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>); + pub struct AltBank2Region1<'d>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>); + pub struct AltBank2Region2<'d>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>); + pub struct AltBank2Region3<'d>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>); pub struct AltFlashLayout<'d> { - _inner: PeripheralRef<'d, FLASH>, - pub bank1_region1: AltBank1Region1, - pub bank1_region2: AltBank1Region2, - pub bank1_region3: AltBank1Region3, - pub bank2_region1: AltBank2Region1, - pub bank2_region2: AltBank2Region2, - pub bank2_region3: AltBank2Region3, + pub bank1_region1: AltBank1Region1<'d>, + pub bank1_region2: AltBank1Region2<'d>, + pub bank1_region3: AltBank1Region3<'d>, + pub bank2_region1: AltBank2Region1<'d>, + pub bank2_region2: AltBank2Region2<'d>, + pub bank2_region3: AltBank2Region3<'d>, } impl<'d> Flash<'d> { pub fn into_alt_regions(self) -> AltFlashLayout<'d> { unsafe { crate::pac::FLASH.optcr().modify(|r| r.set_db1m(true)) }; + + // SAFETY: We never expose the cloned peripheral references, and their instance is not public. + // Also, all flash region operations are protected with a cs. + let mut p = self.release(); AltFlashLayout { - _inner: self.release(), - bank1_region1: Bank1Region1(&BANK1_REGION1), - bank1_region2: Bank1Region2(&BANK1_REGION2), - bank1_region3: AltBank1Region3(&ALT_BANK1_REGION3), - bank2_region1: AltBank2Region1(&ALT_BANK2_REGION1), - bank2_region2: AltBank2Region2(&ALT_BANK2_REGION2), - bank2_region3: AltBank2Region3(&ALT_BANK2_REGION3), + bank1_region1: Bank1Region1(&BANK1_REGION1, unsafe { p.clone_unchecked() }), + bank1_region2: Bank1Region2(&BANK1_REGION2, unsafe { p.clone_unchecked() }), + bank1_region3: AltBank1Region3(&ALT_BANK1_REGION3, unsafe { p.clone_unchecked() }), + bank2_region1: AltBank2Region1(&ALT_BANK2_REGION1, unsafe { p.clone_unchecked() }), + bank2_region2: AltBank2Region2(&ALT_BANK2_REGION2, unsafe { p.clone_unchecked() }), + bank2_region3: AltBank2Region3(&ALT_BANK2_REGION3, unsafe { p.clone_unchecked() }), } } }