diff options
| author | Rasmus Melchior Jacobsen <[email protected]> | 2023-04-05 10:27:13 +0200 |
|---|---|---|
| committer | Rasmus Melchior Jacobsen <[email protected]> | 2023-04-05 10:27:13 +0200 |
| commit | 95b31cf2db647b8d1779cc3f7439d5c7df98f379 (patch) | |
| tree | d9a4b31dae641e4984f2b20fd060c43503bcb645 | |
| parent | e2e15e436a63ea89a98c8f9f513ccb5e5a3fd115 (diff) | |
Remove Drop on Flash and FlashLayout and propage lifetime to region types
This allows the user to "split" the FlashRegions struct into each region
| -rw-r--r-- | embassy-stm32/build.rs | 11 | ||||
| -rw-r--r-- | embassy-stm32/src/flash/common.rs | 20 | ||||
| -rw-r--r-- | 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 9df5a58d6..61aceed93 100644 --- a/embassy-stm32/build.rs +++ b/embassy-stm32/build.rs | |||
| @@ -148,7 +148,8 @@ fn main() { | |||
| 148 | 148 | ||
| 149 | let region_type = format_ident!("{}", get_flash_region_type_name(region.name)); | 149 | let region_type = format_ident!("{}", get_flash_region_type_name(region.name)); |
| 150 | flash_regions.extend(quote! { | 150 | flash_regions.extend(quote! { |
| 151 | pub struct #region_type(pub &'static crate::flash::FlashRegion); | 151 | #[cfg(flash)] |
| 152 | pub struct #region_type<'d>(pub &'static crate::flash::FlashRegion, pub(crate) embassy_hal_common::PeripheralRef<'d, crate::peripherals::FLASH>,); | ||
| 152 | }); | 153 | }); |
| 153 | } | 154 | } |
| 154 | 155 | ||
| @@ -159,11 +160,11 @@ fn main() { | |||
| 159 | let field_name = format_ident!("{}", region_name.to_lowercase()); | 160 | let field_name = format_ident!("{}", region_name.to_lowercase()); |
| 160 | let field_type = format_ident!("{}", get_flash_region_type_name(f.name)); | 161 | let field_type = format_ident!("{}", get_flash_region_type_name(f.name)); |
| 161 | let field = quote! { | 162 | let field = quote! { |
| 162 | pub #field_name: #field_type | 163 | pub #field_name: #field_type<'d> |
| 163 | }; | 164 | }; |
| 164 | let region_name = format_ident!("{}", region_name); | 165 | let region_name = format_ident!("{}", region_name); |
| 165 | let init = quote! { | 166 | let init = quote! { |
| 166 | #field_name: #field_type(&#region_name) | 167 | #field_name: #field_type(&#region_name, unsafe { p.clone_unchecked()}) |
| 167 | }; | 168 | }; |
| 168 | 169 | ||
| 169 | (field, (init, region_name)) | 170 | (field, (init, region_name)) |
| @@ -174,15 +175,13 @@ fn main() { | |||
| 174 | flash_regions.extend(quote! { | 175 | flash_regions.extend(quote! { |
| 175 | #[cfg(flash)] | 176 | #[cfg(flash)] |
| 176 | pub struct FlashLayout<'d> { | 177 | pub struct FlashLayout<'d> { |
| 177 | _inner: embassy_hal_common::PeripheralRef<'d, crate::peripherals::FLASH>, | ||
| 178 | #(#fields),* | 178 | #(#fields),* |
| 179 | } | 179 | } |
| 180 | 180 | ||
| 181 | #[cfg(flash)] | 181 | #[cfg(flash)] |
| 182 | impl<'d> FlashLayout<'d> { | 182 | impl<'d> FlashLayout<'d> { |
| 183 | pub(crate) const fn new(p: embassy_hal_common::PeripheralRef<'d, crate::peripherals::FLASH>) -> Self { | 183 | pub(crate) fn new(mut p: embassy_hal_common::PeripheralRef<'d, crate::peripherals::FLASH>) -> Self { |
| 184 | Self { | 184 | Self { |
| 185 | _inner: p, | ||
| 186 | #(#inits),* | 185 | #(#inits),* |
| 187 | } | 186 | } |
| 188 | } | 187 | } |
diff --git a/embassy-stm32/src/flash/common.rs b/embassy-stm32/src/flash/common.rs index c48b2f2ea..8235d6f08 100644 --- a/embassy-stm32/src/flash/common.rs +++ b/embassy-stm32/src/flash/common.rs | |||
| @@ -38,18 +38,6 @@ impl<'d> Flash<'d> { | |||
| 38 | } | 38 | } |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | impl Drop for Flash<'_> { | ||
| 42 | fn drop(&mut self) { | ||
| 43 | unsafe { family::lock() }; | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | impl Drop for FlashLayout<'_> { | ||
| 48 | fn drop(&mut self) { | ||
| 49 | unsafe { family::lock() }; | ||
| 50 | } | ||
| 51 | } | ||
| 52 | |||
| 53 | fn blocking_read(base: u32, size: u32, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { | 41 | fn blocking_read(base: u32, size: u32, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { |
| 54 | if offset + bytes.len() as u32 > size { | 42 | if offset + bytes.len() as u32 > size { |
| 55 | return Err(Error::Size); | 43 | return Err(Error::Size); |
| @@ -177,7 +165,7 @@ impl FlashRegion { | |||
| 177 | 165 | ||
| 178 | foreach_flash_region! { | 166 | foreach_flash_region! { |
| 179 | ($type_name:ident, $write_size:literal, $erase_size:literal) => { | 167 | ($type_name:ident, $write_size:literal, $erase_size:literal) => { |
| 180 | impl crate::_generated::flash_regions::$type_name { | 168 | impl crate::_generated::flash_regions::$type_name<'_> { |
| 181 | pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { | 169 | pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { |
| 182 | blocking_read(self.0.base, self.0.size, offset, bytes) | 170 | blocking_read(self.0.base, self.0.size, offset, bytes) |
| 183 | } | 171 | } |
| @@ -191,11 +179,11 @@ foreach_flash_region! { | |||
| 191 | } | 179 | } |
| 192 | } | 180 | } |
| 193 | 181 | ||
| 194 | impl embedded_storage::nor_flash::ErrorType for crate::_generated::flash_regions::$type_name { | 182 | impl embedded_storage::nor_flash::ErrorType for crate::_generated::flash_regions::$type_name<'_> { |
| 195 | type Error = Error; | 183 | type Error = Error; |
| 196 | } | 184 | } |
| 197 | 185 | ||
| 198 | impl embedded_storage::nor_flash::ReadNorFlash for crate::_generated::flash_regions::$type_name { | 186 | impl embedded_storage::nor_flash::ReadNorFlash for crate::_generated::flash_regions::$type_name<'_> { |
| 199 | const READ_SIZE: usize = 1; | 187 | const READ_SIZE: usize = 1; |
| 200 | 188 | ||
| 201 | fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> { | 189 | fn read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Self::Error> { |
| @@ -207,7 +195,7 @@ foreach_flash_region! { | |||
| 207 | } | 195 | } |
| 208 | } | 196 | } |
| 209 | 197 | ||
| 210 | impl embedded_storage::nor_flash::NorFlash for crate::_generated::flash_regions::$type_name { | 198 | impl embedded_storage::nor_flash::NorFlash for crate::_generated::flash_regions::$type_name<'_> { |
| 211 | const WRITE_SIZE: usize = $write_size; | 199 | const WRITE_SIZE: usize = $write_size; |
| 212 | const ERASE_SIZE: usize = $erase_size; | 200 | const ERASE_SIZE: usize = $erase_size; |
| 213 | 201 | ||
diff --git a/embassy-stm32/src/flash/f4.rs b/embassy-stm32/src/flash/f4.rs index 2f5b417cc..2ce9df69f 100644 --- a/embassy-stm32/src/flash/f4.rs +++ b/embassy-stm32/src/flash/f4.rs | |||
| @@ -45,34 +45,36 @@ mod alt_regions { | |||
| 45 | &ALT_BANK2_REGION3, | 45 | &ALT_BANK2_REGION3, |
| 46 | ]; | 46 | ]; |
| 47 | 47 | ||
| 48 | pub type AltBank1Region1 = Bank1Region1; | 48 | pub type AltBank1Region1<'d> = Bank1Region1<'d>; |
| 49 | pub type AltBank1Region2 = Bank1Region2; | 49 | pub type AltBank1Region2<'d> = Bank1Region2<'d>; |
| 50 | pub struct AltBank1Region3(&'static FlashRegion); | 50 | pub struct AltBank1Region3<'d>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>); |
| 51 | pub struct AltBank2Region1(&'static FlashRegion); | 51 | pub struct AltBank2Region1<'d>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>); |
| 52 | pub struct AltBank2Region2(&'static FlashRegion); | 52 | pub struct AltBank2Region2<'d>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>); |
| 53 | pub struct AltBank2Region3(&'static FlashRegion); | 53 | pub struct AltBank2Region3<'d>(pub &'static FlashRegion, PeripheralRef<'d, FLASH>); |
| 54 | 54 | ||
| 55 | pub struct AltFlashLayout<'d> { | 55 | pub struct AltFlashLayout<'d> { |
| 56 | _inner: PeripheralRef<'d, FLASH>, | 56 | pub bank1_region1: AltBank1Region1<'d>, |
| 57 | pub bank1_region1: AltBank1Region1, | 57 | pub bank1_region2: AltBank1Region2<'d>, |
| 58 | pub bank1_region2: AltBank1Region2, | 58 | pub bank1_region3: AltBank1Region3<'d>, |
| 59 | pub bank1_region3: AltBank1Region3, | 59 | pub bank2_region1: AltBank2Region1<'d>, |
| 60 | pub bank2_region1: AltBank2Region1, | 60 | pub bank2_region2: AltBank2Region2<'d>, |
| 61 | pub bank2_region2: AltBank2Region2, | 61 | pub bank2_region3: AltBank2Region3<'d>, |
| 62 | pub bank2_region3: AltBank2Region3, | ||
| 63 | } | 62 | } |
| 64 | 63 | ||
| 65 | impl<'d> Flash<'d> { | 64 | impl<'d> Flash<'d> { |
| 66 | pub fn into_alt_regions(self) -> AltFlashLayout<'d> { | 65 | pub fn into_alt_regions(self) -> AltFlashLayout<'d> { |
| 67 | unsafe { crate::pac::FLASH.optcr().modify(|r| r.set_db1m(true)) }; | 66 | unsafe { crate::pac::FLASH.optcr().modify(|r| r.set_db1m(true)) }; |
| 67 | |||
| 68 | // SAFETY: We never expose the cloned peripheral references, and their instance is not public. | ||
| 69 | // Also, all flash region operations are protected with a cs. | ||
| 70 | let mut p = self.release(); | ||
| 68 | AltFlashLayout { | 71 | AltFlashLayout { |
| 69 | _inner: self.release(), | 72 | bank1_region1: Bank1Region1(&BANK1_REGION1, unsafe { p.clone_unchecked() }), |
| 70 | bank1_region1: Bank1Region1(&BANK1_REGION1), | 73 | bank1_region2: Bank1Region2(&BANK1_REGION2, unsafe { p.clone_unchecked() }), |
| 71 | bank1_region2: Bank1Region2(&BANK1_REGION2), | 74 | bank1_region3: AltBank1Region3(&ALT_BANK1_REGION3, unsafe { p.clone_unchecked() }), |
| 72 | bank1_region3: AltBank1Region3(&ALT_BANK1_REGION3), | 75 | bank2_region1: AltBank2Region1(&ALT_BANK2_REGION1, unsafe { p.clone_unchecked() }), |
| 73 | bank2_region1: AltBank2Region1(&ALT_BANK2_REGION1), | 76 | bank2_region2: AltBank2Region2(&ALT_BANK2_REGION2, unsafe { p.clone_unchecked() }), |
| 74 | bank2_region2: AltBank2Region2(&ALT_BANK2_REGION2), | 77 | bank2_region3: AltBank2Region3(&ALT_BANK2_REGION3, unsafe { p.clone_unchecked() }), |
| 75 | bank2_region3: AltBank2Region3(&ALT_BANK2_REGION3), | ||
| 76 | } | 78 | } |
| 77 | } | 79 | } |
| 78 | } | 80 | } |
