diff options
| author | okhsunrog <[email protected]> | 2025-05-21 20:59:49 +0300 |
|---|---|---|
| committer | okhsunrog <[email protected]> | 2025-05-21 20:59:49 +0300 |
| commit | 966186064ebf36634e9930dd4b2d83ed675f6eb0 (patch) | |
| tree | 072428d7c1d0ae30f914db953bd4c81af6db4210 /embassy-stm32/src | |
| parent | be831d0e7990ab07cc805f440d3814ae47c6dfcc (diff) | |
fix UB
Diffstat (limited to 'embassy-stm32/src')
| -rw-r--r-- | embassy-stm32/src/flash/eeprom.rs | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/embassy-stm32/src/flash/eeprom.rs b/embassy-stm32/src/flash/eeprom.rs index 5bccb2ecc..68bcc6c15 100644 --- a/embassy-stm32/src/flash/eeprom.rs +++ b/embassy-stm32/src/flash/eeprom.rs | |||
| @@ -154,6 +154,7 @@ impl<'d> Flash<'d, Blocking> { | |||
| 154 | /// This method will write unaligned prefix and suffix as bytes, and aligned middle as u32. | 154 | /// This method will write unaligned prefix and suffix as bytes, and aligned middle as u32. |
| 155 | pub fn eeprom_write_slice(&mut self, offset: u32, data: &[u8]) -> Result<(), Error> { | 155 | pub fn eeprom_write_slice(&mut self, offset: u32, data: &[u8]) -> Result<(), Error> { |
| 156 | self.check_eeprom_offset(offset, data.len() as u32)?; | 156 | self.check_eeprom_offset(offset, data.len() as u32)?; |
| 157 | |||
| 157 | let start = offset; | 158 | let start = offset; |
| 158 | let misalign = (start % 4) as usize; | 159 | let misalign = (start % 4) as usize; |
| 159 | let prefix_len = if misalign == 0 { | 160 | let prefix_len = if misalign == 0 { |
| @@ -163,17 +164,24 @@ impl<'d> Flash<'d, Blocking> { | |||
| 163 | }; | 164 | }; |
| 164 | let (prefix, rest) = data.split_at(prefix_len); | 165 | let (prefix, rest) = data.split_at(prefix_len); |
| 165 | let aligned_len = (rest.len() / 4) * 4; | 166 | let aligned_len = (rest.len() / 4) * 4; |
| 166 | let (aligned, suffix) = rest.split_at(aligned_len); | 167 | let (bytes_for_u32_write, suffix) = rest.split_at(aligned_len); |
| 167 | 168 | ||
| 168 | unsafe { | 169 | unsafe { |
| 169 | family::unlock(); | 170 | family::unlock(); |
| 170 | if !prefix.is_empty() { | 171 | if !prefix.is_empty() { |
| 171 | self.eeprom_write_u8_slice_unlocked(start, prefix)?; | 172 | self.eeprom_write_u8_slice_unlocked(start, prefix)?; |
| 172 | } | 173 | } |
| 173 | if !aligned.is_empty() { | 174 | if !bytes_for_u32_write.is_empty() { |
| 174 | let aligned_offset = start + prefix_len as u32; | 175 | let aligned_eeprom_offset = start + prefix_len as u32; |
| 175 | let u32_data = core::slice::from_raw_parts(aligned.as_ptr() as *const u32, aligned.len() / 4); | 176 | let base_eeprom_addr = EEPROM_BASE as u32 + aligned_eeprom_offset; |
| 176 | self.eeprom_write_u32_slice_unlocked(aligned_offset, u32_data)?; | 177 | for (i, chunk) in bytes_for_u32_write.chunks_exact(4).enumerate() { |
| 178 | // Safely read a u32 from a potentially unaligned pointer into the chunk. | ||
| 179 | let value = (chunk.as_ptr() as *const u32).read_unaligned(); | ||
| 180 | let current_eeprom_addr = base_eeprom_addr + (i * 4) as u32; | ||
| 181 | core::ptr::write_volatile(current_eeprom_addr as *mut u32, value); | ||
| 182 | family::wait_ready_blocking()?; | ||
| 183 | family::clear_all_err(); | ||
| 184 | } | ||
| 177 | } | 185 | } |
| 178 | if !suffix.is_empty() { | 186 | if !suffix.is_empty() { |
| 179 | let suffix_offset = start + (prefix_len + aligned_len) as u32; | 187 | let suffix_offset = start + (prefix_len + aligned_len) as u32; |
