This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

LP-CC2652RB: Watchdog not resetting MCU when using BIM

Part Number: LP-CC2652RB

Tool/software:

Hello. I was playing around with the watchdog settings and found out it was not working at all. I've looked through other topics and my watchdog configuration seems to be correct:

    Watchdog_init();
    Watchdog_Params_init(&wdgParams);
    wdgParams.callbackFxn = (Watchdog_Callback) wdgCallback;
    wdgParams.resetMode = Watchdog_RESET_ON;
    wdgParams.debugStallMode = Watchdog_DEBUG_STALL_ON;

    wdgHandle = Watchdog_open(CONFIG_WATCHDOG_0, &wdgParams);

    if (!wdgHandle)
    {
        while (1)
            ;
    }

    uint32_t tickValue = Watchdog_convertMsToTicks(wdgHandle, 10000);
    Watchdog_setReload(wdgHandle, tickValue);

Void wdgCallback(UArg handle)
{
    SysCtrlSystemReset();
}

As far as I understand from the documentation, the watchdog counts to zero on the first, the counter value is reloaded and, on the second countdown to zero, the MCU should restart. However, this seems to have no effect. I put a breakpoint inside the callback and checked the WDT registers using memory view. The registers for the watchdog seem to be correctly set: control register has value 0x07 (NMI, Reset Enabled, Interrupt Enabled), RIS is 0x01 (timeout event occurred) and MIS is 0x01 (timeout event occurred). Even so, the board reset and code restart I was expecting does not happen. If I'm debugging when this happens, I get an error that the debugger disconnects, but it appears to not be a real reset.

I've also read that it is unsafe to call OS APIs in an NMI context, so I tried two other things in the watchdog callback: a while(1) loop and writing to the reset register manually, as done in SysCtrlSystemReset ( HWREGBITW( AON_PMCTL_BASE + AON_PMCTL_O_RESETCTL, AON_PMCTL_RESETCTL_SYSRESET_BITN ) = 1; ). Neither of these work.

I have a two threaded program, one being the zigbee stack and the other being my own thread on which I do sensor measurements and keep an alive led. I can tell that the watchdog does not work because I have an LED that blinks a few times when starting the board and an alive led that blinks every 10 seconds. The boot up led never lights up. I never reset the watchdog, so I would expect the board to reset itself every 10 seconds as configured in the watchdog initialization procedure.

I tried the provided watchdog example and it works as expected, but that is a single threaded program. When activating watchdog0 from sys cfg, does the zigbee stack detect it and clear the watchdog by itself? 

For the moment, I want to be able to force a board reset at fixed intervals, but it seems that not clearing the watchdog is not enough. Calling SysCtrlSystemReset using a util_timer also does not work.

How can I force a board reset under certain conditions? 

  • Hello,

    The Watchdog does not tick while in Standby mode (only ticks in Idle or Active).
    Please see relevant post here: https://e2e.ti.com/support/wireless-connectivity/zigbee-thread-group/zigbee-and-thread/f/zigbee-thread-forum/789856/cc2652r-using-watchdog-resets-in-standby-mode-instead-of-paused-as-described-in-the-datasheet

    In the Watchdog SDK Example, the device is likely in Active/Idle (not Standby) when the Watchdog triggers.

    For Zigbee example, are you using a Zigbee End Device (zed)?
    If yes, then that device will stay in standby most of its lifetime, and the Active/Idle time may not be long enough to trigger your 10sec Watchdog timeout.
    To prevent Standby for testing Watchdog, can you try to call "Power_disablePolicy();" as done in the Watchdog example? This should keep the Watchdog ticking.

    Thanks,
    Toby

  • Thank for your reply!

    For Zigbee example, are you using a Zigbee End Device (zed)?

    Yes! I did not know this was an important detail, hence my omission to mention this.

    I've did more tests and, indeed, the MCU does not restart even when the callback is called. I managed to force a periodic restart by using a timer, so that works for the moment.

    However, were I to need an actual recovery from a hard fault / undesirable state, can I achieve this while allowing the CPU to sleep as expected for the periods during which the MCU works correctly? As far as I've understood the documentation, the interrupt generated by a watchdog is called in a NMI context, so no high level APIs can be called. I've tried printing to the console from the watchdog interrupt and it doesn't work. Does this apply to Power_disablePolicy as well?

    Were that to work, is it enough to call Power_disablePolicy in the interrupt and enter a while(1) loop there to force a restart?

  • Calling "SysCtrlSystemReset();" should be enough to induce a reset of the device.

    However, were I to need an actual recovery from a hard fault / undesirable state, can I achieve this while allowing the CPU to sleep as expected for the periods during which the MCU works correctly?

    For this device, watchdog will not count in Standby since it is sourced from the HF (high frequency clock) which does not operate in standby. Timers can run in Standby since they are dependent on RTC (real time clock which depends on LF, low frequency clock, which does tick in Standby) so a separate mechanism would be needed to achieve that (such as what you've implemented with timers).

    I've tried printing to the console from the watchdog interrupt and it doesn't work

    This does not work, since the printout (usually UART) drivers pend on RTOS semaphores, which cannot be called in an interrupt context (and in general no blocking calls should be made in interrupts). If you use low level driver calls (e.g. UARTCharPutNonBlocking), then I think printing would work.

  • Hello Toby. Thanks for the info, I've managed to successfully reset the board using SysCtrlSystemReset and a timer. 

    Additional question so as to not start a new topic regarding a ZED temperature project: Apart from the zigbee stack, I've added another task that deals with sensor measurements which I use to update the variables whose pointers are stored in the Attribute definition (MS TEMP measured value, MS HUM measured value). Do I always need to guard the updates to the variables with a semaphore from within my task? Is it safe to update the variables without any concurrency protection? 

  • Hello,

    Apologies for my delay.

    In general, it is good practice to update the variables within a Critical Section to synchronize it between 2 or more threads/etc.

    Without this, there is always risk that a stale value could be read/used. Some use cases gracefully handle this case, e.g. if temperature is going from 24C to 26C, but an application uses stale value of 24C or 25C, then actual operation could still be ok.

    Thanks,
    Toby