how to use the AVR watchdog

Go To Last Post
25 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have scanned through the first number of tutorial pages, and did a google search on avrfreaks on using the watchdog, but I come up empty  on a tutorial on watchdog usage.

Is there a tutorial on the use of the watchdog?

 

what I want to do is:

during normal program execution the watchdog is off. there are no things blocking so at this point I think I do not need it there.

But I have a couple of possible crash situations were I want to enable the watchdog and let that trigger a HW reset.

example 1 is my main for loop that should never ever exit, but if it does... turn on watchdog and that will never be reset so it will trigger a complete system restart.

second is when I want to power off the system. If for some reason the power off does not work I want the watchdog to get triggered and then let that give a system reset.

 

I have never worked with the watchdog and before I start asking a lot of questions that most likely will be answered in a tutorial I want to have read that first.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Calculate you max execution time in main and select an appropriate WDT timeout. Just before you go into your While loop start the WDT, and put a WDT Reset at the end of the loop. As long as your code hits the reset the WDT will stay in its doghouse, if the reset is not hit the WDT will bark and reset the AVR.

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Which compliler you have using?

If AVRGCC then it's for you smiley

For wiki: http://microchipdeveloper.com/8a...
For <avr/wdt.h>: https://www.nongnu.org/avr-libc/...

And https://www.pocketmagic.net/avr-...

#include <avr/io.h>
#include <avr/interrupt.h>

#include <avr/wdt.h> /*Watchdog timer handling*/

int main(void)
{
	/*First step is Enable Watchdog*/
	wdt_enable(WDTO_8S); /*Watchdog Reset after 8Sec*/
			     /*WDTO_15MS , WDTO_30MS..etc for deffernt time*/
				/*for more time*/
			     /*https://www.nongnu.org/avr-libc/user-manual/group__avr__watchdog.html */

	while(1)
	{
		/*Here your code executing*/
		/*Then second step for Watchdog is Reset you Watchdog timer*/
		wdt_reset();
	}
}

 

শূন্য  - The ZeRo

Last Edited: Sun. Feb 3, 2019 - 06:08 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't know of a tutorial....

 

If you need the watchdog in your project, then

keep it on all the time.  Turning it on and off

just when you think it might be needed will

probably cause more problems.

 

Your code just needs to regularly reset the

watchdog timer to avoid a watchdog reset.

The timer period can be as long as 8 seconds

on some AVR models (and 2 seconds on older

chips) which is quite a long time for an MCU.

 

So in your main function, add enough calls to

wdt_reset() to ensure the watchdog timeout

period will not be exceeded.  (This C function

generates a single wdr assembler instruction.)

 

--Mike

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

+1 to what Mike just said.

 

But note that in all but the most trivial program watchdog is not something you bolt on at the end when  everything else is done and then you think "I think I'll throw in a bit of last minute protection".

 

Watchdog should be something you design in from the start and every subsequent design decision is predicated on "how will this interact with the watchdog?"

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

+1 to Cliff's comment.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I use the watchdog in an M328P much as you describe. In my case, I have it as a failsafe for sleep, in case the wakeup event fails to happen while it is sleeping (it could, possibly happen other times, and never wake it up). So, I do turn it on and off. It works fine. 

 

The important thing to remember about watchdog is that you have to pet it just right. It takes TWO operations (within, I think, 4 MCU clock cycles) to change the operating mode and maybe the timeout interval. 

 

For a failsafe like this, you really never need to reset it. You start it, just before the operation to be guarded, begins. You stop it when that operation is over. BUT, be very careful about that remote possibility that the watchdog might time out and get hungry. So, you need to make sure that you do, or don't ( depending on the MCU you use ) have the interrupt service routine and that you have the necessary control bits set so that it all does what you want.

 

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you need the watchdog in your project, then keep it on all the time.

Some of the newer processors only let you change the watchdog configuration once (ie "turn it on at boot time"), so you don't have much choice in the matter.  I guess the idea is that it's primarily a "bad code path" detector, and you wouldn't want to have people die just because your bad code happened to turn off the watchdog...  (I think it's a bit over-protective, given the other protections usually wrapped around changing the WD status, but... worth considering.)

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Jack Ganssle has written some nice documentation / tutorials about effective use of watchdog timers.

https://duckduckgo.com/html?q=jack+ganssle+watchdog+tutorial

Doing magic with a USD 7 Logic Analyser: https://www.avrfreaks.net/comment/2421756#comment-2421756

Bunch of old projects with AVR's: http://www.hoevendesign.com

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Note the default value of the WDT is 16ms on most mega's, so if you use a longer period, be sure you handle the timeout pretty quickly in your start up code as a reset will 'reset' your timeout to this short period!

If not handled properly and quickly, will lead to a "hung" micro that resets - wdt timeout- reset - wdt timeout - reset, don't ask me how I know this!  sad

 

Jim

 

Click Link: Get Free Stock: Retire early! PM for strategy

share.robinhood.com/jamesc3274
stack gold/silver https://www.onegold.com/join/713...

 

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for all the great replies.

I am using a AtMega1281 in the project that I want to be using the Watchdog in.

 

I have really never ever used the watchdog but it seems to be straight forward in usage.

I always have event based systems and in general make sure these events do not take to long to process, so that seems to be the way to go with using the watchdog.

 

From what I understand so far is that at initial power on the watchdog is disabled by default ( note that I never program the watchdog fuse)

So then it is not important what is done to it, but after a watchdog generated reset it seems to be such that the watchdog is not turned off, but changes to the shortest interval time possible. Which as said will cause problems if you do not take that into account.

So this means that the second thing I have to do (first is setting the IO ports to a after reset state, just plain PORT & DDR registers writing) is either turn the watchdog off, or set it to a very long time interval.

At this point I think I will opt for leaving/turning it on and setting it to 8seconds time-out which will be way more than needed.

Then I will do the full system initialization and when that is done change the watchdog to 2 seconds. an event should never last longer than a second anyway or the system might run into memory problems. so 2 seconds between ticks should be more than enough. Then I can choose in the special situations to speed up or just let the timer be.

 

Interestingly while looking at the AVRgcc documentation the wdt library does not have a standard function call to turn the watchdog off.

you call wdt_enable for turning it on and set the interval ( assume that when I want to change the interval I also call this function). and a wdt_reset that you have to cal regularly to not trigger the watchdog.

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

meslomp wrote:
So this means that the second thing I have to do (first is setting the IO ports to a after reset state, just plain PORT & DDR registers writing) is either turn the watchdog off, or set it to a very long time interval.
It'll depend on your C compiler but most have a way to intercept the early C startup so you can service the watchdog even before the loops that set up BSS and .data. For example in avr-gcc one would use a .init3 routine to achieve this.
meslomp wrote:
Interestingly while looking at the AVRgcc documentation the wdt library does not have a standard function call to turn the watchdog off.
as noted above the idea of switching it off is a bit of anathema - either you use it or you don't. If you do then you simply enable it by the fuse or by a call to configure it as early as possible. Once on it stays on. Interesting to see Bill's comment in #8 - so some new AVR don't give you a choice - it's a one way switch.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have made a file with 4 functions:

1: function to turn watchdog ON

void WDT_Turn_On(const uint8_t a_time)
{
	wdt_enable(a_time);
}

 

2: function to change the interval

void WDT_Set_Interval(const uint8_t a_time)
{
	wdt_enable(a_time);
}

 

3: a function that will reset the watchdog

void WDT_Do_Reset(void)
{
	wdt_reset();
}

4: a function that will turn off the watchdog

void WDT_Turn_Off(void)
{
	uint8_t l_Sreg;
		
	l_Sreg = SREG;						// store SREG state specially for global interrupt enable
	cli();								// turn off interrupts
	wdt_reset();						// reset watchdog
	MCUSR &= ~(1<<WDRF);				// make sure WDRF is cleared in MCU status reg or else watchdog cannot be turned off
	WDTCSR |= (1<<WDCE) | (1<<WDE);		// send special value to command register enabling it to be editted
	WDTCSR = 0x00;						// turn off watchdog by clearing WDE & WDIE plus all the rest
	SREG = l_Sreg;						// restore SREG. if interrupts were enabled they will be again
}

 

now the first 2 are the same, but when you go through the code it is clear what the function is actually doing.

 

in fact the first 3 are just re-definitions of the functions in the avr/wdt library and are a shell for me to in now and a year to still understand what is going on.

 

the 4th function I copied from the datasheet

 

I am just wondering if I need to reset the watchdog myself before changing the interval or if that is done inside the library.

And personally I am still in doubt if I not going to make the "turn on" function turn the wdt on always at 8 seconds, and then use the set interval to change it later on in the process.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

meslomp wrote:

Interestingly while looking at the AVRgcc documentation the wdt library does not have a standard function call to turn the watchdog off.

 

My include/avr/wdt.h file has wdt_disable() with

a few variations for different chips.

 

--Mike

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avr-mike wrote:

My include/avr/wdt.h file has wdt_disable() with

a few variations for different chips.

 

--Mike

 

That is interesting as the documentation does not mention it.

it only mentions a macro define for the reset command, a couple of defines for the interval time setting and an enable function.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

meslomp wrote:
That is interesting as the documentation does not mention it.
Sort of:

 

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The watchdog isn’t there to catch bad code - although it tends to do that. Even with defect free software (!) the watchdog is there to catch situations that can’t be detected (not without special hardware) like an ESD event flipping a bit in a register or ram that sends the micro off the rails. Having the watchdog interrupt is next to useless - if it fired the train has already crashed. The stack pointer might be out the window, so whilst you might beable to enter the isr, don’t try calling any functions or relying onthe ram to be sensible.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
Having the watchdog interrupt is next to useless
Well yes and no - it does give the opportunity to get the outputs into a "safe" state (like stopping motors and stuff).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hardware should take care of that.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

joeymorin wrote:

meslomp wrote:
That is interesting as the documentation does not mention it.
Sort of:

 

Indeed did not notice that.

 

kartman,

 

one thing I want to protect is my main loop, which technically is a for(;;){code}

if it ever exits then I want the watchdog to kick in, simply as then indeed things are terribly wrong.

there is a second place and that is when I want to power down.

At this moment I put everything in a power down state and then cut power(should be suicide)

If for some reason that does not go right I would need to technically go through reset to restart the system so could just start executing from address 0 again. But I want all the peripherals to also be reset to their reset state and using the watchdog seems to be the simplest way to do that, specially as I now want to have it for code protection.

I do not plan on using the interrupt, although I might also use that during debugging ( trigger interrupt to spit out debug data before dying. but that will not be there in the code I want to eventually use. watchdog is just plain reset as indeed registers or anything can be corrupt so the data is no longer trusted to be correct.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

meslomp wrote:
which technically is a for(;;){code} if it ever exits
Go on. How can an infinite loop ever exit (unless a deliberate "break;" is performed) ?? If you write:

int main(void) {
    while(1) {
        PORTB = rand();
    }
    PORTB = 0x55;
}

I bet the compiler will even warn you about "unreachable code". There is no way that PORTB = 0x55 line can ever be reached. Of course if I wrote:

int main(void) {
    while(1) {
        PORTB = rand();
        if (somecondition) break;
    }
    PORTB = 0x55;
}

then there is a chance that it could be.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It has been a while since I had some time to do some coding and check things.

Clawson, you are right. I think it has been some left over code from another project were there was a posibility for the code to break out of the for loop when something in the system went wrong. There I just did a pc jump to reset and the system woudl start running again. 

 

I have tested the posted code and it works fine.... to good actually, hahahahah

was testing some things were if I pressed a button I would display data on my LCD and freeze the program to be able to do some measurements.

I normally use a for(;;) loop to achieve that when possible.

Took me a while to figure out why the bloody thing would reset after I did a couple measurements as I always ended up at the same pin to measure, then to realize I had enabled the watchdog, but forgot to reset it inside that for loop. So the reset on each pass of the normal operational loop was OK.

After disabling the watchdog through my routine all went OK. I still have to check if the undocumented wdt_disable function actually is there I did not have time to do that.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

meslomp wrote:
I normally use a for(;;) loop to achieve that when possible.
If you are going to "retrofit" watchdog support (rather than design it in from the start) then you need to analyse every code path in your code and consider where the intentional "long loops" are then sprinkle liberally with WDRs

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:
Having the watchdog interrupt is next to useless - if it fired the train has already crashed.

I don't think I'm the only 'Freak here that uses the watchdog as a wakeup timer.  Especially in deep-sleep apps that are battery powered.

 

So I certainly cannot agree with "useless".  But

1)  The power budget for watch crystal and timer2 async clocking on some/many modern AVR8 models is about the same as the WD, in power-down.  So a case could be made for not using the WD for that.

1a)  And that will have better accuracy than WD, if that is important to the app.

2)  When using it for periodic wakeup, one must carefully code to use it as a real watchdog also.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

meslomp wrote:
I normally use a for(;;) loop to achieve that when possible.
If you are going to "retrofit" watchdog support (rather than design it in from the start) then you need to analyse every code path in your code and consider where the intentional "long loops" are then sprinkle liberally with WDRs

I have set the watchdog to 8 seconds for now as I already thought I needed to do that, but at this moment seems to be a lot of work and I want to finish to a certain state in not to long.

I have already done a couple of multi hour tests with he watchdog running and all seemed to be OK, I have not seen resets occur. If that was to happen the device would power down, so no way to miss it as I found out while halting my program.

 

what I have is an event driven system. before checking if there are new events I reset the watchdog. then handle the event and start again with clearing the timer. as there are a couple of events that should be handled within a second of occurring or things might go bad ( have not seen that happening) for now I think it is safe to say that setting the watchdog at 8 seconds and being sure that at least a reset is given every 2seconds I should be OK for now.

It does not take away the fact though that I will have and will be going to check how long events are actually taking, but as said I now first want to have my code in a usable state in not to long a time as I want to do some practical testing in a couple of weeks when we are on holiday.