Check watchdog load value max value before multiplying by 2, to avoid integer overflow

This commit is contained in:
Jan Niehusmann 2022-10-12 22:39:14 +00:00
parent 39190c357f
commit 84b92edd30

View file

@ -41,7 +41,7 @@ use fugit::MicrosDurationU32;
/// Watchdog peripheral /// Watchdog peripheral
pub struct Watchdog { pub struct Watchdog {
watchdog: WATCHDOG, watchdog: WATCHDOG,
delay_us: u32, load_value: u32, // decremented by 2 per tick (µs)
} }
impl Watchdog { impl Watchdog {
@ -49,7 +49,7 @@ impl Watchdog {
pub fn new(watchdog: WATCHDOG) -> Self { pub fn new(watchdog: WATCHDOG) -> Self {
Self { Self {
watchdog, watchdog,
delay_us: 0, load_value: 0,
} }
} }
@ -110,7 +110,7 @@ impl Watchdog {
impl watchdog::Watchdog for Watchdog { impl watchdog::Watchdog for Watchdog {
fn feed(&mut self) { fn feed(&mut self) {
self.load_counter(self.delay_us) self.load_counter(self.load_value)
} }
} }
@ -120,19 +120,23 @@ impl watchdog::WatchdogEnable for Watchdog {
fn start<T: Into<Self::Time>>(&mut self, period: T) { fn start<T: Into<Self::Time>>(&mut self, period: T) {
const MAX_PERIOD: u32 = 0xFFFFFF; const MAX_PERIOD: u32 = 0xFFFFFF;
let delay_us = period.into().to_micros();
if delay_us > MAX_PERIOD / 2 {
panic!(
"Period cannot exceed maximum load value of {} ({} microseconds))",
MAX_PERIOD,
MAX_PERIOD / 2
);
}
// Due to a logic error, the watchdog decrements by 2 and // Due to a logic error, the watchdog decrements by 2 and
// the load value must be compensated; see RP2040-E1 // the load value must be compensated; see RP2040-E1
self.delay_us = period.into().to_micros() * 2; self.load_value = delay_us * 2;
if self.delay_us > MAX_PERIOD {
panic!("Period cannot exceed maximum load value of {}", MAX_PERIOD);
}
self.enable(false); self.enable(false);
unsafe { unsafe {
self.configure_wdog_reset_triggers(); self.configure_wdog_reset_triggers();
} }
self.load_counter(self.delay_us); self.load_counter(self.load_value);
self.enable(true); self.enable(true);
} }
} }