Skip to content

watchdog_get_count() never decrements #349

@cryptoAlgorithm

Description

@cryptoAlgorithm

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    questionFurther information is requestedwontfixThis will not be worked on

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions