Documentation update for watchdog_get_time_remaining_xx() functions. (Suggestion) #2819

Open
opened 2026-02-06 09:59:05 -06:00 by NormanDunbar · 12 comments
NormanDunbar commented 2026-02-06 09:59:05 -06:00 (Migrated from github.com)

I've been playing with the 2.2.0 SDK and the watchdog. I notice from sections 5.1.32.3.5 and 5.1.32.3.6 describing watchdog_get_time_remaining_ms() and watchdog_get_time_remaining_us that they return the last value set and not, as hoped for, the time remaining. (I've seen and noted issue #1492)

In my test app, I noticed that irrespective of how often I changed and re-flashed with the debug-probe, it continued to give me the original (first) setting I used. I eventually worked out that a re-flash doesn't (appear to) reboot the device, unlike the Arduinos I'm used to, so the value reported stays stuck at whatever value was current when the last power cycle took place.

Example:

  1. watchdog_enable(4000,1);.
  2. Allow a watchdog initiated reboot to occur.
  3. watchdog_get_time_remaining_ms() reports 4000.
  4. Change to watchdog_enable(5000,1);.
  5. Re-flash.
  6. watchdog_get_time_remaining_ms() still reports 4000.
  7. Change to watchdog_enable(6000,1);.
  8. Re-flash again.
  9. watchdog_get_time_remaining_ms() still reports 4000.
  10. Power cycle the board.
  11. watchdog_get_time_remaining_ms() now reports 6000.

I know, I know, it's not a huge problem, given that the hardware bug causes the wrong result anyway, but it drove me mad for ages until I hit reset (I have a push-button between RUN and GND pins to save me ripping (another) Micro USB off of a Pico board!

Perhaps, the docs could mention something like "On RP2040 this method returns the value set prior to the most recent power cycle instead of the remaining time due to a h/w bug. Re-flashing doesn't perform a power cycle, so changes will not be reported."

My testing code:

//============================================================
// The watchdog timer will reset the Pico if its countdown
// timer reaches zero. In this example we set the timeout to
// ten seconds, and allow debugging to operate nortmally, then
// slow blink the status LED a few times, feeding the watchdog
// each time - no reset happens.
//
// After that, an infinite loop is entered to fast blink the 
// status LED until the watchdog timer expires and the board
// is reset. On rebooting, the boot status is checked to see
// if the watchdog performed the most recent reboot, or
// otherwise.
//
// Norman Dunbar.
// February 4 2026.
//============================================================
// NOTE.
//
// You will see some "return 0" statements in the code, used
// when the Status LED isn't supported or won't initialise. In
// embedded systems, returning from main() is considered a 
// no-no! However, with the Pico, returning from main() will
// call exit() which then calls _exit(), which spins. So, we
// can safely return from main().
//============================================================

#include <stdio.h>
#include "pico/stdlib.h"
#include "hardware/watchdog.h"
#include "pico/status_led.h" 

// Watchdog timeout, eight seconds. Longer than
// 8,388 milliseconds results in 8,388 being set.
const uint32_t watchdogDelay_ms = 8000;
const uint32_t longSleep_ms = watchdogDelay_ms/10;
const uint32_t shortSleep_ms = watchdogDelay_ms/30;

int main() {
    stdio_init_all();

    // Detect the reboot status, normal power on or watchdog
    // initiated reboot.
    if (watchdog_enable_caused_reboot()) {
        printf("Watchdog reboot detected.\n");
    } else {
        printf("Normal boot detected.\n");
    }

    // Enable the watchdog with a 10 second timeout.
    // "True lets debugger run without watchdog rebooting."
    // Delay is 24 bits but because of bug RP2040-E1, the 
    // counter reduces by 2 each time, so maximum is 23 bits
    // so, 8,388,608 microseconds/8,388 milliseconds.
    watchdog_enable(watchdogDelay_ms, true);

     // Is Status LED supported?
    if (!status_led_supported()) {
        printf("Status LED not supported.\n");
        return 0;
    }

    // Will Status LED initialise?
    if (!status_led_init()) {
        printf("Status LED failed to initialise.\n");
        return 0;
    }

    // Loop 5 times slow blinking the status LED every 
    // watchdogDelay/10 seconds. (Default = 1 second.).
    // Reset the watchdog every time around. 
    for (uint8_t i = 0; i < 5; i++) {
        status_led_set_state(true);
        sleep_ms(longSleep_ms);
        status_led_set_state(false);
        sleep_ms(longSleep_ms);

        // Feed the watchdog! Prevents a reboot.
        watchdog_update();
        printf("The watchdog has been fed. (%d)\n", i);
    }

    // Loop fast blinking the status LED every second.
    // This time, the watchdog is not being fed, so we will
    // get rebooted after watchdogDelay seconds.
    printf("I've stopped feeding the watchdog, will it notice?\n");

    // BUG! Doesn't work. Also, needs power cycle to report
    // any changes to the initial setting.
    printf("Reboot in %u milliseconds\n", 
        watchdog_get_time_remaining_ms());
        
    while (true) {
        status_led_set_state(true);
        sleep_ms(shortSleep_ms);
        status_led_set_state(false);
        sleep_ms(shortSleep_ms);
    }
}

Cheers,
Norm.

I've been playing with the 2.2.0 SDK and the watchdog. I notice from sections 5.1.32.3.5 and 5.1.32.3.6 describing `watchdog_get_time_remaining_ms()` and `watchdog_get_time_remaining_us` that they return the _last value set_ and not, as hoped for, the time remaining. (I've seen and noted issue #1492) In my test app, I noticed that irrespective of how often I changed and re-flashed with the debug-probe, it continued to give me the original (first) setting I used. I eventually worked out that a re-flash doesn't (appear to) reboot the device, unlike the Arduinos I'm used to, so the value reported stays stuck at whatever value was current when _the last power cycle_ took place. Example: 1. `watchdog_enable(4000,1);`. 3. Allow a watchdog initiated reboot to occur. 4. `watchdog_get_time_remaining_ms()` reports 4000. 5. Change to `watchdog_enable(5000,1);`. 6. Re-flash. 7. `watchdog_get_time_remaining_ms()` _still_ reports 4000. 8. Change to `watchdog_enable(6000,1);`. 9. Re-flash again. 10. `watchdog_get_time_remaining_ms()` _still_ reports 4000. 11. Power cycle the board. 12. `watchdog_get_time_remaining_ms()` now reports 6000. I know, I know, it's not a huge problem, given that the hardware bug causes the wrong result anyway, but it drove me mad for ages until I hit reset (I have a push-button between `RUN` and `GND` pins to save me ripping (another) Micro USB off of a Pico board! Perhaps, the docs could mention something like "On RP2040 this method returns the value set `prior to the most recent power cycle` instead of the remaining time due to a h/w bug. Re-flashing doesn't perform a power cycle, so changes will not be reported." My testing code: ``` //============================================================ // The watchdog timer will reset the Pico if its countdown // timer reaches zero. In this example we set the timeout to // ten seconds, and allow debugging to operate nortmally, then // slow blink the status LED a few times, feeding the watchdog // each time - no reset happens. // // After that, an infinite loop is entered to fast blink the // status LED until the watchdog timer expires and the board // is reset. On rebooting, the boot status is checked to see // if the watchdog performed the most recent reboot, or // otherwise. // // Norman Dunbar. // February 4 2026. //============================================================ // NOTE. // // You will see some "return 0" statements in the code, used // when the Status LED isn't supported or won't initialise. In // embedded systems, returning from main() is considered a // no-no! However, with the Pico, returning from main() will // call exit() which then calls _exit(), which spins. So, we // can safely return from main(). //============================================================ #include <stdio.h> #include "pico/stdlib.h" #include "hardware/watchdog.h" #include "pico/status_led.h" // Watchdog timeout, eight seconds. Longer than // 8,388 milliseconds results in 8,388 being set. const uint32_t watchdogDelay_ms = 8000; const uint32_t longSleep_ms = watchdogDelay_ms/10; const uint32_t shortSleep_ms = watchdogDelay_ms/30; int main() { stdio_init_all(); // Detect the reboot status, normal power on or watchdog // initiated reboot. if (watchdog_enable_caused_reboot()) { printf("Watchdog reboot detected.\n"); } else { printf("Normal boot detected.\n"); } // Enable the watchdog with a 10 second timeout. // "True lets debugger run without watchdog rebooting." // Delay is 24 bits but because of bug RP2040-E1, the // counter reduces by 2 each time, so maximum is 23 bits // so, 8,388,608 microseconds/8,388 milliseconds. watchdog_enable(watchdogDelay_ms, true); // Is Status LED supported? if (!status_led_supported()) { printf("Status LED not supported.\n"); return 0; } // Will Status LED initialise? if (!status_led_init()) { printf("Status LED failed to initialise.\n"); return 0; } // Loop 5 times slow blinking the status LED every // watchdogDelay/10 seconds. (Default = 1 second.). // Reset the watchdog every time around. for (uint8_t i = 0; i < 5; i++) { status_led_set_state(true); sleep_ms(longSleep_ms); status_led_set_state(false); sleep_ms(longSleep_ms); // Feed the watchdog! Prevents a reboot. watchdog_update(); printf("The watchdog has been fed. (%d)\n", i); } // Loop fast blinking the status LED every second. // This time, the watchdog is not being fed, so we will // get rebooted after watchdogDelay seconds. printf("I've stopped feeding the watchdog, will it notice?\n"); // BUG! Doesn't work. Also, needs power cycle to report // any changes to the initial setting. printf("Reboot in %u milliseconds\n", watchdog_get_time_remaining_ms()); while (true) { status_led_set_state(true); sleep_ms(shortSleep_ms); status_led_set_state(false); sleep_ms(shortSleep_ms); } } ``` Cheers, Norm.
peterharperuk commented 2026-02-06 10:28:59 -06:00 (Migrated from github.com)

Re-flashing doesn't perform a power cycle, so changes will not be reported

What do you do when you "reflash" exactly?
Do you do "monitor reset init"?

> Re-flashing doesn't perform a power cycle, so changes will not be reported What do you do when you "reflash" exactly? Do you do "monitor reset init"?
NormanDunbar commented 2026-02-07 01:12:32 -06:00 (Migrated from github.com)

Morning.

I'm using the VSCode extension, to refresh I simply click the Pico icon over on the left toolbar, then click the "Flash project (SWD)" option. That refreshes the board, but if the board has already had a watchdog timeout, any amended watchdog delay is misreported.

Cheers,
Norm.

Morning. I'm using the VSCode extension, to refresh I simply click the Pico icon over on the left toolbar, then click the "Flash project (SWD)" option. That refreshes the board, but if the board has already had a watchdog timeout, any amended watchdog delay is misreported. Cheers, Norm.
NormanDunbar commented 2026-02-07 09:42:23 -06:00 (Migrated from github.com)

Hmmm, I think I see a problem. Here's the output from the "Flash Project (SWD)" command:


Open On-Chip Debugger 0.12.0+dev (2025-10-09-12:15)
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
Info : [rp2040.core0] Hardware thread awareness created
Info : [rp2040.core1] Hardware thread awareness created
Info : Using CMSIS-DAPv2 interface with VID:PID=0x2e8a:0x000c, serial=E6614103E7551E24
Info : CMSIS-DAP: SWD supported
Info : CMSIS-DAP: Atomic commands supported
Info : CMSIS-DAP: Test domain timer supported
Info : CMSIS-DAP: FW Version = 2.0.0
Info : CMSIS-DAP: Interface Initialised (SWD)
Info : SWCLK/TCK = 0 SWDIO/TMS = 0 TDI = 0 TDO = 0 nTRST = 0 nRESET = 0
Info : CMSIS-DAP: Interface ready
Info : clock speed 5000 kHz
Info : SWD DPIDR 0x0bc12477, DLPIDR 0x00000001
Info : SWD DPIDR 0x0bc12477, DLPIDR 0x10000001
Info : [rp2040.core0] Cortex-M0+ r0p1 processor detected
Info : [rp2040.core0] target has 4 breakpoints, 2 watchpoints
Info : [rp2040.core0] Examination succeed
Info : [rp2040.core1] Cortex-M0+ r0p1 processor detected
Info : [rp2040.core1] target has 4 breakpoints, 2 watchpoints
Info : [rp2040.core1] Examination succeed
Info : [rp2040.core0] starting gdb server on 3333
Info : Listening on port 3333 for gdb connections
[rp2040.core0] halted due to debug-request, current mode: Thread 
xPSR: 0xf1000000 pc: 0x000000ee msp: 0x20041f00
[rp2040.core1] halted due to debug-request, current mode: Thread 
xPSR: 0xf1000000 pc: 0x000000ee msp: 0x20041f00
Info : RP2040 rev 1, QSPI Flash win w25q16jv id = 0x1540ef size = 2048 KiB in 512 sectors

Error: Invalid command argument
Error: [rp2040.core0] Execution of event reset-init failed:
args[i] option value ('CX') is not valid

** Programming Started **
Info : Padding image section 1 at 0x10004c58 with 168 bytes (bank write end alignment)
Warn : Adding extra erase range, 0x10004d00 .. 0x10004fff
** Programming Finished **
** Verify Started **
** Verified OK **
** Resetting Target **
shutdown command invoked
 *  Terminal will be reused by tasks, press any key to close it. 

However, that appears to be before the programming started. Plus, the taska.json file doesn't show a "CX" parameter for the flash command:

       {
            "label": "Flash",
            "type": "process",
            "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
            "args": [
                "-s",
                "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts",
                "-f",
                "interface/cmsis-dap.cfg",
                "-f",
                "target/${command:raspberry-pi-pico.getTarget}.cfg",
                "-c",
                "adapter speed 5000; program \"${command:raspberry-pi-pico.launchTargetPath}\" verify reset exit"
            ],
            "problemMatcher": [],
            "windows": {
                "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe",
            }
Hmmm, I think I see a problem. Here's the output from the "Flash Project (SWD)" command: ``` * Executing task: /home/norman/.pico-sdk/openocd/0.12.0+dev/openocd.exe -s /home/norman/.pico-sdk/openocd/0.12.0+dev/scripts -f interface/cmsis-dap.cfg -f target/rp2040.cfg -c adapter speed 5000; program "/home/norman/SourceCode/RaspberryPico_C_Programming/Code/Watchdog/build/watchdog.elf" verify reset exit Open On-Chip Debugger 0.12.0+dev (2025-10-09-12:15) Licensed under GNU GPL v2 For bug reports, read http://openocd.org/doc/doxygen/bugs.html Info : [rp2040.core0] Hardware thread awareness created Info : [rp2040.core1] Hardware thread awareness created Info : Using CMSIS-DAPv2 interface with VID:PID=0x2e8a:0x000c, serial=E6614103E7551E24 Info : CMSIS-DAP: SWD supported Info : CMSIS-DAP: Atomic commands supported Info : CMSIS-DAP: Test domain timer supported Info : CMSIS-DAP: FW Version = 2.0.0 Info : CMSIS-DAP: Interface Initialised (SWD) Info : SWCLK/TCK = 0 SWDIO/TMS = 0 TDI = 0 TDO = 0 nTRST = 0 nRESET = 0 Info : CMSIS-DAP: Interface ready Info : clock speed 5000 kHz Info : SWD DPIDR 0x0bc12477, DLPIDR 0x00000001 Info : SWD DPIDR 0x0bc12477, DLPIDR 0x10000001 Info : [rp2040.core0] Cortex-M0+ r0p1 processor detected Info : [rp2040.core0] target has 4 breakpoints, 2 watchpoints Info : [rp2040.core0] Examination succeed Info : [rp2040.core1] Cortex-M0+ r0p1 processor detected Info : [rp2040.core1] target has 4 breakpoints, 2 watchpoints Info : [rp2040.core1] Examination succeed Info : [rp2040.core0] starting gdb server on 3333 Info : Listening on port 3333 for gdb connections [rp2040.core0] halted due to debug-request, current mode: Thread xPSR: 0xf1000000 pc: 0x000000ee msp: 0x20041f00 [rp2040.core1] halted due to debug-request, current mode: Thread xPSR: 0xf1000000 pc: 0x000000ee msp: 0x20041f00 Info : RP2040 rev 1, QSPI Flash win w25q16jv id = 0x1540ef size = 2048 KiB in 512 sectors ``` **Error: Invalid command argument Error: [rp2040.core0] Execution of event reset-init failed: args[i] option value ('CX') is not valid** ``` ** Programming Started ** Info : Padding image section 1 at 0x10004c58 with 168 bytes (bank write end alignment) Warn : Adding extra erase range, 0x10004d00 .. 0x10004fff ** Programming Finished ** ** Verify Started ** ** Verified OK ** ** Resetting Target ** shutdown command invoked * Terminal will be reused by tasks, press any key to close it. ``` However, that appears to be before the programming started. Plus, the taska.json file doesn't show a "CX" parameter for the flash command: ``` { "label": "Flash", "type": "process", "command": "${userHome}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", "args": [ "-s", "${userHome}/.pico-sdk/openocd/0.12.0+dev/scripts", "-f", "interface/cmsis-dap.cfg", "-f", "target/${command:raspberry-pi-pico.getTarget}.cfg", "-c", "adapter speed 5000; program \"${command:raspberry-pi-pico.launchTargetPath}\" verify reset exit" ], "problemMatcher": [], "windows": { "command": "${env:USERPROFILE}/.pico-sdk/openocd/0.12.0+dev/openocd.exe", } ```
lurch commented 2026-02-07 09:50:14 -06:00 (Migrated from github.com)

You seem to be claiming that the time set with watchdog_enable is getting "latched", and if you set a different time with another call to watchdog_enable, then the value returned by watchdog_get_time_remaining_ms is still reporting the first time that you set, and not the updated time. And that a power-cycle is needed to actually clear this "latched" value. Is that correct? If so, you may have discovered a new hardware bug?

Looking at the code in https://github.com/raspberrypi/pico-sdk/blob/develop/src/rp2_common/hardware_watchdog/watchdog.c , watchdog_enable calls _watchdog_enable, which updates load_value and then calls watchdog_update which finally loads the load_value into the watchdog's LOAD register. And watchdog_get_time_remaining_ms then reads the TIME field of the watchdog's CTRL register.
I'd expect an update of the watchdog's LOAD register to be reflected by the TIME field of the watchdog's CTRL register (see section 4.7.6 of the RP2040 Datasheet).

Update: Oh, I see from your newly-added comment that the problem might be that your Pico isn't getting reflashed correctly, which is a much more likely explanation for the behaviour you're seeing 😉
pinging @will-v-pi as he's the person most familiar with the inner workings of our Pico VS Code extension.

You seem to be claiming that the time set with `watchdog_enable` is getting "latched", and if you set a _different_ time with another call to `watchdog_enable`, then the value returned by `watchdog_get_time_remaining_ms` is still reporting the _first_ time that you set, and not the updated time. And that a power-cycle is needed to actually clear this "latched" value. Is that correct? If so, you may have discovered a new hardware bug? Looking at the code in https://github.com/raspberrypi/pico-sdk/blob/develop/src/rp2_common/hardware_watchdog/watchdog.c , [`watchdog_enable`](https://github.com/raspberrypi/pico-sdk/blob/develop/src/rp2_common/hardware_watchdog/watchdog.c#L81) calls [` _watchdog_enable`](https://github.com/raspberrypi/pico-sdk/blob/develop/src/rp2_common/hardware_watchdog/watchdog.c#L48), which updates [`load_value`](https://github.com/raspberrypi/pico-sdk/blob/develop/src/rp2_common/hardware_watchdog/watchdog.c#L68) and then calls [`watchdog_update`](https://github.com/raspberrypi/pico-sdk/blob/develop/src/rp2_common/hardware_watchdog/watchdog.c#L26) which finally loads the `load_value` into the watchdog's `LOAD` register. And [`watchdog_get_time_remaining_ms`](https://github.com/raspberrypi/pico-sdk/blob/develop/src/rp2_common/hardware_watchdog/watchdog.c#L42) then reads the `TIME` field of the watchdog's `CTRL` register. I'd _expect_ an update of the watchdog's `LOAD` register to be reflected by the `TIME` field of the watchdog's `CTRL` register (see section 4.7.6 of the RP2040 Datasheet). Update: Oh, I see from your newly-added comment that the problem might be that your Pico isn't getting reflashed correctly, which is a much more likely explanation for the behaviour you're seeing 😉 pinging @will-v-pi as he's the person most familiar with the inner workings of our Pico VS Code extension.
peterharperuk commented 2026-02-07 10:02:29 -06:00 (Migrated from github.com)

I was wondering if it's being reflashed but not reset

I was wondering if it's being reflashed but not reset
NormanDunbar commented 2026-02-07 10:04:18 -06:00 (Migrated from github.com)

Afternoon @lurch,

My complete code is somewhere above, if you feel the urge to try it! But pretty much what happens is I allow the watchdog to timeout and reset the board with value, say, 4000 ms. I decided that was too short, and made it 6000 ms, and reflashed, but it still reported 4000.

After playing around, I found that no matter how many times I changed the timeout and reflashed the board, if I didn't do a power cycle, the value was never reported as the current timeout. Here's the Serial Monitor output from an initial 8000 ms, reflashed with 4000.

  1. Start with power on and the current timeout at 8000 ms. Note that the last two lines show an 8 second time difference.
Normal boot detected.
15:59:01:658 -> The watchdog has been fed. (0)
15:59:03:261 -> The watchdog has been fed. (1)
15:59:04:863 -> The watchdog has been fed. (2)
15:59:06:467 -> The watchdog has been fed. (3)
15:59:08:070 -> The watchdog has been fed. (4)
15:59:08:072 -> I've stopped feeding the watchdog, will it notice?
15:59:08:076 -> Reboot in 8000 milliseconds
15:59:16:069 -> Watchdog reboot detected.
---- Closed the serial port /dev/ttyACM0 ----
  1. I stopped monitoring while changing the timeout to 4000 ms and reflashing. Then restarted monitoring:
---- Opened the serial port /dev/ttyACM0 ----
15:59:39:420 -> Watchdog reboot detected.
15:59:40:238 -> The watchdog has been fed. (0)
15:59:41:039 -> The watchdog has been fed. (1)
15:59:41:843 -> The watchdog has been fed. (2)
15:59:42:647 -> The watchdog has been fed. (3)
15:59:43:449 -> The watchdog has been fed. (4)
15:59:43:451 -> I've stopped feeding the watchdog, will it notice?
15:59:43:456 -> Reboot in 8000 milliseconds
15:59:47:448 -> Watchdog reboot detected.
  1. 8000 is wrong, it should be 4000, and the reboot did indeed take 4 seconds, not 8. Power cycle now.
15:59:49:052 -> Normal boot detected.
15:59:50:967 -> The watchdog has been fed. (0)
15:59:51:770 -> The watchdog has been fed. (1)
15:59:52:572 -> The watchdog has been fed. (2)
15:59:53:375 -> The watchdog has been fed. (3)
15:59:54:178 -> The watchdog has been fed. (4)
15:59:54:180 -> I've stopped feeding the watchdog, will it notice?
15:59:54:184 -> Reboot in 4000 milliseconds
15:59:58:178 -> Watchdog reboot detected.
---- Closed the serial port /dev/ttyACM0 ----

Finally, we get the new value, but only after the power cycle.

Cheers,
Norm.

Afternoon @lurch, My complete code is somewhere above, if you feel the urge to try it! But pretty much what happens is I allow the watchdog to timeout and reset the board with value, say, 4000 ms. I decided that was too short, and made it 6000 ms, and reflashed, but it still reported 4000. After playing around, I found that no matter how many times I changed the timeout and reflashed the board, if I didn't do a power cycle, the value was never reported as the current timeout. Here's the Serial Monitor output from an initial 8000 ms, reflashed with 4000. 1. Start with power on and the current timeout at 8000 ms. Note that the last two lines show an 8 second time difference. ``` Normal boot detected. 15:59:01:658 -> The watchdog has been fed. (0) 15:59:03:261 -> The watchdog has been fed. (1) 15:59:04:863 -> The watchdog has been fed. (2) 15:59:06:467 -> The watchdog has been fed. (3) 15:59:08:070 -> The watchdog has been fed. (4) 15:59:08:072 -> I've stopped feeding the watchdog, will it notice? 15:59:08:076 -> Reboot in 8000 milliseconds 15:59:16:069 -> Watchdog reboot detected. ---- Closed the serial port /dev/ttyACM0 ---- ``` 2. I stopped monitoring while changing the timeout to 4000 ms and reflashing. Then restarted monitoring: ``` ---- Opened the serial port /dev/ttyACM0 ---- 15:59:39:420 -> Watchdog reboot detected. 15:59:40:238 -> The watchdog has been fed. (0) 15:59:41:039 -> The watchdog has been fed. (1) 15:59:41:843 -> The watchdog has been fed. (2) 15:59:42:647 -> The watchdog has been fed. (3) 15:59:43:449 -> The watchdog has been fed. (4) 15:59:43:451 -> I've stopped feeding the watchdog, will it notice? 15:59:43:456 -> Reboot in 8000 milliseconds 15:59:47:448 -> Watchdog reboot detected. ``` 3. 8000 is wrong, it should be 4000, and the reboot did indeed take 4 seconds, not 8. Power cycle now. ``` 15:59:49:052 -> Normal boot detected. 15:59:50:967 -> The watchdog has been fed. (0) 15:59:51:770 -> The watchdog has been fed. (1) 15:59:52:572 -> The watchdog has been fed. (2) 15:59:53:375 -> The watchdog has been fed. (3) 15:59:54:178 -> The watchdog has been fed. (4) 15:59:54:180 -> I've stopped feeding the watchdog, will it notice? 15:59:54:184 -> Reboot in 4000 milliseconds 15:59:58:178 -> Watchdog reboot detected. ---- Closed the serial port /dev/ttyACM0 ---- ``` Finally, we get the new value, but only after the power cycle. Cheers, Norm.
NormanDunbar commented 2026-02-07 10:07:17 -06:00 (Migrated from github.com)

I was wondering if it's being reflashed but not reset

Looking at the tail end of the reflash, after the error I noted above, I see this:

** Programming Started **
Info : Padding image section 1 at 0x10004c58 with 168 bytes (bank write end alignment)
Warn : Adding extra erase range, 0x10004d00 .. 0x10004fff
** Programming Finished **
** Verify Started **
** Verified OK **
** Resetting Target **
shutdown command invoked
 *  Terminal will be reused by tasks, press any key to close it. 

So, the error came before flashing started, and after flashing and verification, the board was indeed reset.

Weird.

Cheers,
Norm.

> I was wondering if it's being reflashed but not reset Looking at the tail end of the reflash, _after_ the error I noted above, I see this: ``` ** Programming Started ** Info : Padding image section 1 at 0x10004c58 with 168 bytes (bank write end alignment) Warn : Adding extra erase range, 0x10004d00 .. 0x10004fff ** Programming Finished ** ** Verify Started ** ** Verified OK ** ** Resetting Target ** shutdown command invoked * Terminal will be reused by tasks, press any key to close it. ``` So, the error came before flashing started, and after flashing and verification, the board was indeed reset. Weird. Cheers, Norm.
NormanDunbar commented 2026-04-04 11:10:13 -05:00 (Migrated from github.com)

Just to add more confusion, I wondered what would be reported if I uploaded the new code with the bootloader, rather than the Debug-Probe. That should reset the board after all? It's even more confusing.

  1. Board was configured with a 2000 ms timeout period.
  2. Code was recompiled with a 4000 ms timeout.
  3. Code uploaded as a UF2 file via the bootloader.
  4. Now the message states that the timeout will be in 250 ms. (This is regardless of the new timeout.)
16:49:20:463 -> Reboot in 250 milliseconds
  1. It does reboot, after the newly configured 4000 ms timeout, and definitely not after 250 ms as reported.
  2. Pressing the run button (I add a button between RUN and GND to my boards) the new timeout is then reported and the board continues to reboot after the new timeout.
16:49:25:445 -> Normal boot detected.
16:49:26:537 -> The watchdog has been fed. (0)
16:49:27:340 -> The watchdog has been fed. (1)
16:49:28:142 -> The watchdog has been fed. (2)
16:49:28:945 -> The watchdog has been fed. (3)
16:49:29:749 -> The watchdog has been fed. (4)
16:49:29:751 -> I've stopped feeding the watchdog, will it notice?
16:49:29:755 -> Reboot in 4000 milliseconds

Cheers,
Norm.

Just to add more confusion, I wondered what would be reported if I uploaded the new code with the bootloader, rather than the Debug-Probe. That should reset the board after all? It's even more confusing. 1. Board was configured with a 2000 ms timeout period. 2. Code was recompiled with a 4000 ms timeout. 3. Code uploaded as a UF2 file via the bootloader. 4. Now the message states that the timeout will be in 250 ms. (This is regardless of the new timeout.) ```16:49:20:457 -> I've stopped feeding the watchdog, will it notice? 16:49:20:463 -> Reboot in 250 milliseconds ``` 5. It does reboot, after the newly configured 4000 ms timeout, and definitely not after 250 ms as reported. 6. Pressing the run button (I add a button between RUN and GND to my boards) the new timeout is then reported and the board continues to reboot after the new timeout. ``` 16:49:25:445 -> Normal boot detected. 16:49:26:537 -> The watchdog has been fed. (0) 16:49:27:340 -> The watchdog has been fed. (1) 16:49:28:142 -> The watchdog has been fed. (2) 16:49:28:945 -> The watchdog has been fed. (3) 16:49:29:749 -> The watchdog has been fed. (4) 16:49:29:751 -> I've stopped feeding the watchdog, will it notice? 16:49:29:755 -> Reboot in 4000 milliseconds ``` Cheers, Norm.
lurch commented 2026-04-06 18:36:50 -05:00 (Migrated from github.com)

Just a guess, but maybe the 250ms value is from the watchdog-reboot triggered by the bootloader at the end of flash writing, and you're somehow reading the old value? And see also https://github.com/raspberrypi/pico-sdk/blob/develop/src/rp2_common/hardware_watchdog/include/hardware/watchdog.h#L147

Just a guess, but maybe the 250ms value is from the watchdog-reboot triggered by the bootloader at the end of flash writing, and you're somehow reading the old value? And see also https://github.com/raspberrypi/pico-sdk/blob/develop/src/rp2_common/hardware_watchdog/include/hardware/watchdog.h#L147
NormanDunbar commented 2026-04-09 05:42:28 -05:00 (Migrated from github.com)

Hi @Lurch.

I have no idea, to be honest! I was just wondering if the "don't show me the current setting, show me the old one" feature still happened when the board was programmed with the bootloader. The resulting 250 mS confused me! (Easily done, to be honest!)

Cheers,
Norm.

Hi @Lurch. I have no idea, to be honest! I was just wondering if the "don't show me the current setting, show me the old one" feature still happened when the board was programmed with the bootloader. The resulting 250 mS confused me! (Easily done, to be honest!) Cheers, Norm.
kilograham commented 2026-04-29 10:04:56 -05:00 (Migrated from github.com)

@lurch is there anything to do here?

@lurch is there anything to do here?
lurch commented 2026-06-29 12:17:44 -05:00 (Migrated from github.com)

Not sure, but I don't have time to investigate right now, so I changed the milestone.

Not sure, but I don't have time to investigate right now, so I changed the milestone.
Sign in to join this conversation.
No milestone
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
gh-raspberrypi/pico-sdk#2819
No description provided.