Skip to content

Commit 9fcf7b9

Browse files
author
Johannes Draaijer
committed
Guard pin speed changes for stm32f107 with interrupt:free
1 parent 8e5ef25 commit 9fcf7b9

File tree

1 file changed

+13
-7
lines changed

1 file changed

+13
-7
lines changed

src/setup.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -296,13 +296,19 @@ mod stm32f1 {
296296
$(
297297
impl AlternateVeryHighSpeed for $PIN {
298298
fn into_af11_very_high_speed(self) {
299-
// SAFETY: this assumes that no other access to the GPIO
300-
// control registers is being performed at the same time.
301-
//
302-
// With the current API, this is the best we can do.
303-
let acrl: &mut _ = &mut unsafe { core::mem::transmute(()) };
304-
let mut pin = self.into_alternate_push_pull(acrl);
305-
pin.set_speed(acrl, IOPinSpeed::Mhz50);
299+
// Within this critical section, modifying the `CRL` register can
300+
// only be unsound if this critical section preempts other code
301+
// that is modifying the same register
302+
cortex_m::interrupt::free(|_| {
303+
// SAFETY: this is sound as long as the API of the HAL and structure of the CRL
304+
// struct does not change. In case the size of the `CRL` struct is changed, compilation
305+
// will fail as `mem::transmute` can only convert between types of the same size.
306+
//
307+
// This guards us from unsound behaviour introduced by point releases of the f1 hal
308+
let acrl: &mut _ = &mut unsafe { core::mem::transmute(()) };
309+
let mut pin = self.into_alternate_push_pull(acrl);
310+
pin.set_speed(acrl, IOPinSpeed::Mhz50);
311+
});
306312
}
307313
}
308314
)*

0 commit comments

Comments
 (0)