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.

resetting watchdog counter

Other Parts Discussed in Thread: MSP430F1232

can i get clarification why this command changes all my setting in the watchdog mode    

 setting  watchdog, nmi falling edge, nmi mode, clear watch counter, aclk

 WDTCTL = WDTPW + WDTNMIES + WDTNMI + WDTCNTCL + WDTSSEL;

 

every time try to reset the watch counter to (0) in ISR basic timer by using,

WDTCTL |= WDTPW + WDTCNTCL;   // this only suppose to reset WDT counter but not NMI setting  

   

my wdtnmies, and wdtnmi and wdtssel is changing to (0) also 

  • Hi James,

    The issue is the '|=' in your instruction that services the watchdog. Effectively, what you are doing is reading the WDTCTL word, ORing it with WDTPW and WDTCNTCL, then writing it back. The issue is that WDTPW = 0x5A, but the password bits (bits 15:8 of WDTCTL) are read as 0x69. This means you are ORing 0x69 with 0x5A, which is 0x7B, which is not a valid watchdog password.

    Try just rewritting the entire register completely when you service, or read it, AND it with 0x00FF to clear the PW bits, then OR it with the bits you want set and the WDTPW.

    Mike
  • Hi James,

    I think the problem here is that you use |= when setting the WDTPW - best practice with WDTCTL is always to use = and set the whole register.

    Here is why: the WDTCTL register is password protected, and you have to provide WDTPW with any access to it. As extra security against unintended access, WDTCTL also reads back a different value for the password than the one that you write in - see the device user's guide WDT section. I saw in some of your other posts you were using an F4xx device, which has this user's guide: www.ti.com/lit/pdf/slau056 See p. 422 section 12.3 Watchdog Timer Registers. In the WDTCTL description, see that it says WDTPW "always read as 069h. Must be written as 05Ah or a PUC is generated".

    So if you use an |=, it is reading the value in WDTCTL back, and it's going to have 0x69 as the WDTPW value in the upper byte of the register. This is then getting OR'ed with the WDTPW value you are trying to write in, 0x05A, resulting in 0x7B being written in for the upper byte of the WDTCTL register. Because this is the wrong password, a PUC reset will occur. This would cause your WDT settings to be cleared to their default values.

    So instead, try rewriting the line as WDTCTL = WDTPW + WDTCNTCL + WDTNMIES + WDTNMI + WDTSSEL; This way you should keep your other bits set the way they were from your initial setup, even though you are writing the whole register with "=".

    Regards,

    Katie

  • Also, it is generally not a good idea to service the watchdog timer in an ISR. The justification for a watchdog is that it will reset your part if you get stuck in an unexpected loop. However, if the device is trapped in a loop, an interrupt could still fire, jumping out of the loop and into the interrupt service route. This means that you would service the watchdog (from the ISR), preventing the device from resetting (as it should if it is trapped).

    The best solution is to service the watchdog during normal code flow outside of all ISRs. This guarantees if the watchdog is serviced, the device is operating as expected.

    Mike
  • Here is a link to a most exhaustive look at watchdogs:

    http://www.barrgroup.com/Embedded-Systems/How-To/Advanced-Watchdog-Timer-Tips

    Quite interesting!

     

  • Mike, the WDT is NOT for detecting improperly written code. It is for the case that the hardware crashes due to supply voltage spikes or ESD. Anything else should be checked in software. Especially the mentioned 'stuck in a loop' event can be easily detected in the mentioned timer loop by checking a global variable that is set by the main code. No need for the WDT to be abused for this job.
    In addition, if you spread WDT reset commands all over your code, this effectively disables its functionality. Especially if you have code that takes longer than the WDT timeout and therefore has to reset it inside the loop - and if the loop never ends, the WDT will still be triggered.

    However, I combine the two: I reset the WDT inside my timer ISR, but only if all threads have responded in time. Each thread can define how often it has to respond. The timer will count a variable up for each thread and when any of them reaches the set limit (which may be many seconds or few milliseconds), it won't trigger the WDT anymore. The threads simply have to set their variable back to 0.
    This way, no thread can prevent the timeout of another thread.

    Todd, your link gives me a 'server not found' error.
  • >WDTCTL |= WDTPW + WDTCNTCL;   // this only suppose to reset WDT counter but not NMI setting  

    With Password protected registers, you have to be careful how you use read-and-modify instructions.

    You should not use bis & bic, or & and, but instead = or mov
    As the password on read-back is different than the password you stored with the write.

    XOR works if you use 0x3300 for password, as it turns the 0x9600 read-back password in to 0xa500 password.
    BIT also works without using password.

  • jens:

    I just clicked on my link, and it did take me to the link. You may want to try starting with http://www.barrgroup.com and then searching for watchdog.

     

  • That's weird.
    If I try to ping barrgroup.com, I get a ping response from 69.163.165.9. However, if I try to open the site on IE or FF, I get a 'server not found' error. A ping to www.barrgroup.com fails with host not found.
    Making a telnet request to barrgroup.com (sending a HTTP request manually) gives me a 'moved permanently' response, pointing to www.barrgroup.com. Another request to barrgroup.com, this time with "www.barrgroup.com" in the header (which can't be done in a browser), gives me a web page (not much to see in a telnet client).
    So apparently, the DNS request for www.barrgroup.com fails for me but note the request for barrgroup.com (that apparently points to the very same server, but refuses to deliver the content). No idea why.

    Edit: now, it suddenly works again, after 10 minutes of experiments (and a day since the first failed attempt). As if my attempts have forced the DNS system to update.

    However, an interesting article indeed. And it basically supports what I wrote. A WDT is primarily for resetting the system in case of a crash, not for 'fixing' poor software. Especially not by simply kicking the dog everywhere. And very few MSP projects are so complex that you can't write firmware that is bug-free :)
    But I think, my approach of using counters rather than flags, gives a much better solution for the problem of different response times for different parts of the code (tasks or pseudo-tasks, depending on whether a multitasker or a state machine is used).
  • Jens,

    I wasn't recommending that a WDT be used for detecting improperly written code. For the stuck in loop, I was referring to something like the while loop waiting for a flag to be set or clear (see USCI code examples for examples of this), where something unexpected externally happens that prevents the expected condition from ever occurring. Now the software is hung, and the only way to fix this is with a reset, or a timer ISR that detects and forces the PC to known safe area of code (although you have to be careful with the stack in this case). In this case, the WDT is a good tool for the job.

    My primary point was that if you service the WDT in a timer interrupt (without additional logic like your solution has), you don't catch the situation where the 430 is stuck in a while loop (like waiting on the flag that never comes from above). The timer ISR will ALWAYS execute (as long as the interrupt is enabled), which services the WDT, then returns right back to the while loop that the device is stuck in, which isn't helpful at all.

    When adding WDT servicing instructions to the code, yes, you must be careful about where you put them to make sure you don't have a block that takes too long to execute and causes a WDT reset. But in the case where a loop never ends, if this is the expected behavior (i.e. a main loop), you need to incorporate servicing the WDT inside the loop. Otherwise, if the loop is supposed to end, and doesn't, this is the exact scenario where a WDT resetting the system is useful.

    Your solution using timers for each thread and resetting the timers in the thread is a good approach for a very complex, multi-threaded system. However, it may be overkill for simpler projects, and use resources that may be needed by the main application (128 bytes of SRAM on some of the smaller G2xxx devices goes away REALLY fast, so every byte matters). This is why I recommend putting the WDT servicing in the main loop.

    I see a fair number of questions/issues relating to the WDT, so I try to clarify the information available on the E2E as much as possible. If my previous post wasn't clear, I apologize for that, and hope this post helps clarify things up.

    Mike
  • Code that might be stuck in a loop should use a timeout for the loop. Maybe a global milliseconds counter and when tit has advanced a certain amount compared to loop entry, then the loop exits with an error.
    A common example is I2C when you wait for the bus to become free while a slave stalls it.

    In general, it is a malpractice to write a loop that may probably loop forever.
    If this is required by design, write a state machine that just tests for the condition once and exits to return later for another test.
    That's how I implemented my SD card insert detection and initialization code. (as it could be that a card is never inserted or is broken)

    I agree about the problem with low ram. However, if a project can't be done properly with the available device, it shouldn't be done improperly with the device but rather be done properly with a different device.
    I know what I'm talking about since we still (since 2006) use an MSP430F1232 in our energy meter. With all 8k flash and 256 bytes ram used to the last drop. And still I'm asked to add more functionality. And each time I have to say 'not with this design'. I refuse to strip the existing code of things like the communication timeout and such. Because I know that I'm blamed if the device later hangs. So far, my boss has accepted this. Well, apparently is the need for the new features not high enough to start a redesign.

**Attention** This is a public forum