-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Fix error in watchdog.h #2497
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Fix error in watchdog.h #2497
Conversation
I wonder whether it's actually returning microseconds. I don't see any division in watchdog_get_time_remaining_ms
|
Hmm, but then the function name should be I see the description on the RP2040 is also different:
I have to say I'm not very familiar with the internals of the Pico SDK. |
I had a look at this last night - I thought it might be a duplicate of an old issue, but I found #715 and #1567 which are similar but not actually the same as the issue here. I guess it shows just how easy it is to mix up milliseconds and microseconds! It does indeed look like it's the comment-description that is correct (i.e. the function is returning microseconds). Looking at the current implementation of If you compare this to the implementation of On top of all that, there's also errata RP2040-E1 which means that RP2040 decrements the wachdog twice per tick. So, putting all of that together, I think that as well as changing the "microseconds" in the comment to "milliseconds" in the return watchdog_hw->ctrl & WATCHDOG_CTRL_TIME_BITS / (1000 * WATCHDOG_XFACTOR); (which means you'll need to move the function below the definition of load_value = delay_ms * 1000;
#if PICO_RP2040
load_value *= 2;
#endif with load_value = delay_ms * (1000 * WATCHDOG_XFACTOR); ? For backwards-compatibility reasons, I guess we have to hope that nobody is relying on the current implementation of |
Ooof, I've just noticed that static inline uint32_t watchdog_get_count(void) {
return watchdog_get_time_remaining_ms();
} so that probably explains why this function is returning milliseconds instead of microseconds. If we change TL;DR - I'm suggesting that perhaps this PR ought to do: diff --git a/src/rp2_common/hardware_watchdog/include/hardware/watchdog.h b/src/rp2_common/hardware_watchdog/include/hardware/watchdog.h
index e6adf65..3fde778 100644
--- a/src/rp2_common/hardware_watchdog/include/hardware/watchdog.h
+++ b/src/rp2_common/hardware_watchdog/include/hardware/watchdog.h
@@ -121,21 +121,20 @@ bool watchdog_caused_reboot(void);
bool watchdog_enable_caused_reboot(void);
/**
- * \brief Returns the number of microseconds before the watchdog will reboot the chip.
+ * \brief Returns the number of milliseconds before the watchdog will reboot the chip.
* \ingroup hardware_watchdog
*
* \if rp2040_specicifc
* On RP2040 this method returns the last value set instead of the remaining time due to a h/w bug.
* \endif
*
- * @return The number of microseconds before the watchdog will reboot the chip.
+ * @return The number of milliseconds before the watchdog will reboot the chip.
*/
uint32_t watchdog_get_time_remaining_ms(void);
// backwards compatibility with SDK < 2.0.0
-static inline uint32_t watchdog_get_count(void) {
- return watchdog_get_time_remaining_ms();
-}
+uint32_t watchdog_get_count(void);
+
#ifdef __cplusplus
}
#endif
diff --git a/src/rp2_common/hardware_watchdog/watchdog.c b/src/rp2_common/hardware_watchdog/watchdog.c
index 45528ce..25ed53b 100644
--- a/src/rp2_common/hardware_watchdog/watchdog.c
+++ b/src/rp2_common/hardware_watchdog/watchdog.c
@@ -28,16 +28,21 @@ void watchdog_update(void) {
}
// end::watchdog_update[]
-uint32_t watchdog_get_time_remaining_ms(void) {
- return watchdog_hw->ctrl & WATCHDOG_CTRL_TIME_BITS;
-}
-
#if PICO_RP2040
-// Note, we have x2 here as the watchdog HW currently decrements twice per tick
+// Note, we have x2 here as the watchdog HW currently decrements twice per tick (errata RP2040-E1)
#define WATCHDOG_XFACTOR 2
#else
#define WATCHDOG_XFACTOR 1
#endif
+
+uint32_t watchdog_get_time_remaining_ms(void) {
+ return (watchdog_hw->ctrl & WATCHDOG_CTRL_TIME_BITS) / (1000 * WATCHDOG_XFACTOR);
+}
+
+uint32_t watchdog_get_count(void) {
+ return (watchdog_hw->ctrl & WATCHDOG_CTRL_TIME_BITS) / WATCHDOG_XFACTOR;
+}
+
// tag::watchdog_enable[]
// Helper function used by both watchdog_enable and watchdog_reboot
void _watchdog_enable(uint32_t delay_ms, bool pause_on_debug) {
@@ -60,10 +65,7 @@ void _watchdog_enable(uint32_t delay_ms, bool pause_on_debug) {
if (!delay_ms) {
hw_set_bits(&watchdog_hw->ctrl, WATCHDOG_CTRL_TRIGGER_BITS);
} else {
- load_value = delay_ms * 1000;
-#if PICO_RP2040
- load_value *= 2;
-#endif
+ load_value = delay_ms * (1000 * WATCHDOG_XFACTOR);
if (load_value > WATCHDOG_LOAD_BITS)
load_value = WATCHDOG_LOAD_BITS; But it's obviously up to @kilograham to decide if this is too much of a backwards-incompatible change. Alternatively we could just decide that the function is misnamed, and do something like this instead: diff --git a/src/rp2_common/hardware_watchdog/include/hardware/watchdog.h b/src/rp2_common/hardware_watchdog/include/hardware/watchdog.h
index e6adf65..709fc79 100644
--- a/src/rp2_common/hardware_watchdog/include/hardware/watchdog.h
+++ b/src/rp2_common/hardware_watchdog/include/hardware/watchdog.h
@@ -130,12 +130,16 @@ bool watchdog_enable_caused_reboot(void);
*
* @return The number of microseconds before the watchdog will reboot the chip.
*/
-uint32_t watchdog_get_time_remaining_ms(void);
+uint32_t watchdog_get_time_remaining_us(void);
+
+// backwards compatibility with SDK < 2.1.2
+#define watchdog_get_time_remaining_ms watchdog_get_time_remaining_us
// backwards compatibility with SDK < 2.0.0
static inline uint32_t watchdog_get_count(void) {
- return watchdog_get_time_remaining_ms();
+ return watchdog_get_time_remaining_us();
}
+
#ifdef __cplusplus
}
#endif
diff --git a/src/rp2_common/hardware_watchdog/watchdog.c b/src/rp2_common/hardware_watchdog/watchdog.c
index 45528ce..88a3651 100644
--- a/src/rp2_common/hardware_watchdog/watchdog.c
+++ b/src/rp2_common/hardware_watchdog/watchdog.c
@@ -28,16 +28,17 @@ void watchdog_update(void) {
}
// end::watchdog_update[]
-uint32_t watchdog_get_time_remaining_ms(void) {
- return watchdog_hw->ctrl & WATCHDOG_CTRL_TIME_BITS;
-}
-
#if PICO_RP2040
-// Note, we have x2 here as the watchdog HW currently decrements twice per tick
+// Note, we have x2 here as the watchdog HW currently decrements twice per tick (errata RP2040-E1)
#define WATCHDOG_XFACTOR 2
#else
#define WATCHDOG_XFACTOR 1
#endif
+
+uint32_t watchdog_get_time_remaining_us(void) {
+ return (watchdog_hw->ctrl & WATCHDOG_CTRL_TIME_BITS) / WATCHDOG_XFACTOR;
+}
+
// tag::watchdog_enable[]
// Helper function used by both watchdog_enable and watchdog_reboot
void _watchdog_enable(uint32_t delay_ms, bool pause_on_debug) { |
Fixes #2496
As said in the issue, the documentation for
watchdog_get_time_remaining_ms
says it returns the time in microseconds, while this should be milliseconds. Function its self is fine, just a small docs error.