Remove Drop on Flash and FlashLayout and propage lifetime to region types

This allows the user to "split" the FlashRegions struct into each region
This commit is contained in:
Rasmus Melchior Jacobsen 2023-04-05 10:27:13 +02:00
parent e2e15e436a
commit 95b31cf2db
3 changed files with 31 additions and 42 deletions

View file

@ -148,7 +148,8 @@ fn main() {
let region_type = format_ident!("{}", get_flash_region_type_name(region.name)); let region_type = format_ident!("{}", get_flash_region_type_name(region.name));
flash_regions.extend(quote! { 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_name = format_ident!("{}", region_name.to_lowercase());
let field_type = format_ident!("{}", get_flash_region_type_name(f.name)); let field_type = format_ident!("{}", get_flash_region_type_name(f.name));
let field = quote! { let field = quote! {
pub #field_name: #field_type pub #field_name: #field_type<'d>
}; };
let region_name = format_ident!("{}", region_name); let region_name = format_ident!("{}", region_name);
let init = quote! { let init = quote! {
#field_name: #field_type(&#region_name) #field_name: #field_type(&#region_name, unsafe { p.clone_unchecked()})
}; };
(field, (init, region_name)) (field, (init, region_name))
@ -174,15 +175,13 @@ fn main() {
flash_regions.extend(quote! { flash_regions.extend(quote! {
#[cfg(flash)] #[cfg(flash)]
pub struct FlashLayout<'d> { pub struct FlashLayout<'d> {
_inner: embassy_hal_common::PeripheralRef<'d, crate::peripherals::FLASH>,
#(#fields),* #(#fields),*
} }
#[cfg(flash)] #[cfg(flash)]
impl<'d> FlashLayout<'d> { 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 { Self {
_inner: p,
#(#inits),* #(#inits),*
} }
} }

View file

@ -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> { fn blocking_read(base: u32, size: u32, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
if offset + bytes.len() as u32 > size { if offset + bytes.len() as u32 > size {
return Err(Error::Size); return Err(Error::Size);
@ -177,7 +165,7 @@ impl FlashRegion {
foreach_flash_region! { foreach_flash_region! {
($type_name:ident, $write_size:literal, $erase_size:literal) => { ($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> { pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> {
blocking_read(self.0.base, self.0.size, offset, bytes) 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; 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; const READ_SIZE: usize = 1;
fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> { 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 WRITE_SIZE: usize = $write_size;
const ERASE_SIZE: usize = $erase_size; const ERASE_SIZE: usize = $erase_size;

View file

@ -45,34 +45,36 @@ mod alt_regions {
&ALT_BANK2_REGION3, &ALT_BANK2_REGION3,
]; ];
pub type AltBank1Region1 = Bank1Region1; pub type AltBank1Region1<'d> = Bank1Region1<'d>;
pub type AltBank1Region2 = Bank1Region2; pub type AltBank1Region2<'d> = Bank1Region2<'d>;
pub struct AltBank1Region3(&'static FlashRegion); pub struct AltBank1Region3<'d>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>);
pub struct AltBank2Region1(&'static FlashRegion); pub struct AltBank2Region1<'d>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>);
pub struct AltBank2Region2(&'static FlashRegion); pub struct AltBank2Region2<'d>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>);
pub struct AltBank2Region3(&'static FlashRegion); pub struct AltBank2Region3<'d>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>);
pub struct AltFlashLayout<'d> { pub struct AltFlashLayout<'d> {
_inner: PeripheralRef<'d, FLASH>, pub bank1_region1: AltBank1Region1<'d>,
pub bank1_region1: AltBank1Region1, pub bank1_region2: AltBank1Region2<'d>,
pub bank1_region2: AltBank1Region2, pub bank1_region3: AltBank1Region3<'d>,
pub bank1_region3: AltBank1Region3, pub bank2_region1: AltBank2Region1<'d>,
pub bank2_region1: AltBank2Region1, pub bank2_region2: AltBank2Region2<'d>,
pub bank2_region2: AltBank2Region2, pub bank2_region3: AltBank2Region3<'d>,
pub bank2_region3: AltBank2Region3,
} }
impl<'d> Flash<'d> { impl<'d> Flash<'d> {
pub fn into_alt_regions(self) -> AltFlashLayout<'d> { pub fn into_alt_regions(self) -> AltFlashLayout<'d> {
unsafe { crate::pac::FLASH.optcr().modify(|r| r.set_db1m(true)) }; 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 { AltFlashLayout {
_inner: self.release(), bank1_region1: Bank1Region1(&BANK1_REGION1, unsafe { p.clone_unchecked() }),
bank1_region1: Bank1Region1(&BANK1_REGION1), bank1_region2: Bank1Region2(&BANK1_REGION2, unsafe { p.clone_unchecked() }),
bank1_region2: Bank1Region2(&BANK1_REGION2), bank1_region3: AltBank1Region3(&ALT_BANK1_REGION3, unsafe { p.clone_unchecked() }),
bank1_region3: AltBank1Region3(&ALT_BANK1_REGION3), bank2_region1: AltBank2Region1(&ALT_BANK2_REGION1, unsafe { p.clone_unchecked() }),
bank2_region1: AltBank2Region1(&ALT_BANK2_REGION1), bank2_region2: AltBank2Region2(&ALT_BANK2_REGION2, unsafe { p.clone_unchecked() }),
bank2_region2: AltBank2Region2(&ALT_BANK2_REGION2), bank2_region3: AltBank2Region3(&ALT_BANK2_REGION3, unsafe { p.clone_unchecked() }),
bank2_region3: AltBank2Region3(&ALT_BANK2_REGION3),
} }
} }
} }