aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorokhsunrog <[email protected]>2025-05-21 20:59:49 +0300
committerokhsunrog <[email protected]>2025-05-21 20:59:49 +0300
commit966186064ebf36634e9930dd4b2d83ed675f6eb0 (patch)
tree072428d7c1d0ae30f914db953bd4c81af6db4210
parentbe831d0e7990ab07cc805f440d3814ae47c6dfcc (diff)
fix UB
-rw-r--r--embassy-stm32/src/flash/eeprom.rs18
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;