-
Notifications
You must be signed in to change notification settings - Fork 4
Description
This is a continuation from the issue in the forums.
I'm encountering an issue with watchdog_get_count() not decrementing, and with further investigation it appears to be a possible hardware bug existing in both revisions B1 and B2.
Software Stack
PlatformIO project with https://github.com/maxgerhardt/platform-raspberrypi.git platform and earlephilhower core.
Reproducible Example
Tested on a B1 RP2040:
#include "pico/stdlib.h"
#include "hardware/watchdog.h"
void setup() {
while (!Serial);
delay(100);
Serial.printf("wdg reset? %d\n", watchdog_caused_reboot());
// Enable watchdog
watchdog_enable(2000, true);
for (uint8_t i = 0; i < 5; i++) {
delay(1000);
Serial.printf("wdg kick, cnt=%ldus\n", watchdog_get_count());
watchdog_update();
}
delay(3000); // Let watchdog reset us
}
void loop(void) {}Forum user dthacher has also reproduced this issue using SDK 1.5.1 with the following (on a B2 chip):
/**
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/watchdog.h"
int main() {
stdio_init_all();
if (watchdog_caused_reboot()) {
printf("Rebooted by Watchdog!\n");
//return 0;
} else {
printf("Clean boot\n");
}
for (volatile uint32_t i = 0; i < 65536; i++) {
uint64_t time = time_us_64();
while (time_us_64() - time > 1000);
}
// Enable the watchdog, requiring the watchdog to be updated every 100ms or the chip will reboot
// second arg is pause on debug which means the watchdog will pause when stepping through code
watchdog_enable(100000, 1);
for (uint32_t i = 0; i < 65536; i++) {
printf("Updating watchdog %d\n", i);
printf("Value %ld\n", watchdog_get_count());
//watchdog_update();
}
// Wait in an infinite loop and don't update the watchdog so it reboots us
printf("Waiting to be rebooted by watchdog\n");
while(1);
}(With USB printf and copy-to-RAM)
Finally, to rat out any compiler bugs, the registers were directly accessed (also by the helpful dthacher) and the issue persists:
for (volatile uint32_t i = 0; i < 65536; i++) {
Serial.printf("Pass: %ld\n", i );
Serial.printf("wdg kick, cnt=%ldus\n", (watchdog_hw->ctrl & WATCHDOG_CTRL_TIME_BITS) / 2 );
delay(100);
}Expected Behaviour
The value of watchdog_get_count() decrements and reflects the actual counter of the watchdog counter.
Actual Behaviour
Following was the log output from my example above (note, on a B1 RP2040):
Reconnecting to /dev/cu.usbmodem1101 .. Connected!
wdg reset? 0
wdg kick, cnt=2000000us
wdg kick, cnt=2000000us
wdg kick, cnt=2000000us
wdg kick, cnt=2000000us
wdg kick, cnt=2000000us
Disconnected (read failed: [Errno 6] Device not configured)
Reconnecting to /dev/cu.usbmodem1101 Connected!
wdg reset? 1
wdg kick, cnt=2000000us
wdg kick, cnt=2000000us
wdg kick, cnt=2000000us
wdg kick, cnt=2000000us
wdg kick, cnt=2000000us
Disconnected (read failed: [Errno 6] Device not configured)
Reconnecting to /dev/cu.usbmodem1101 Connected!
wdg reset? 1
wdg kick, cnt=2000000us
wdg kick, cnt=2000000us
wdg kick, cnt=2000000us
wdg kick, cnt=2000000us
wdg kick, cnt=2000000us
As we can see, it appears that the value returned by watchdog_get_count() never decrements and instead is constantly "stuck" at the initial value the watchdog was set up with. It is not a case of the watchdog not running, as it does reset the chip correctly on timing out.