Watchdog Reset

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

Hi All,

 

 

I'm wondering if it is possible to detect where in a program a watchdog reset occurred?

 

I was thinking to have a global variable that I assign specific valuesin different sections of program where and when a watchdog reset might occur

then when a reset occurs, do the following:

- read MCUSR

- check watchdog bit

- if bit set, then read that global variable to determine reset location

 

main question is, will watchdog reset clear that variable? or is there a place where data can be saved before a watchdog reset?

 

 

Thanks!

 

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

daniel123123123 wrote:
I'm wondering if it is possible to detect where in a program a watchdog reset occurred?

On the surface, that is an "interesting" question.  When your program is functioning normally, you will not get watchdog resets.

 

So when you DO get one, it is because something weird happened.  IT COULD BE ANYTHING OR ANYWHERE.

 

daniel123123123 wrote:
main question is, will watchdog reset clear that variable? or is there a place where data can be saved before a watchdog reset?

Now you need to tell us much more.  AVR model, language, toolchain, version, ...

 

In a typical C toolchain for an AVR, the watchdog reset is ... a reset.  Same actions will be taken as with any other reset.  Startup sequence for your toolchain will be invoked.  In the rules of C that includes initialization per the rules of C.

 

Now, your particular toolchain might have "noinit" options.  Let's say that it does.  How are you going to capture your information?

 

But all is not lost, depending on your answers to the questions above.  Modern AVR8 models have "watchdog interrupt" feature.  So you could dig back into the stack to find the "come from" address.  You then might want to use the "interrupt+reset" watchdog setup.

 

I don't know what good that address would do for you.  Log to EEPROM for later readout and analysis?

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

Quite a common technique is to have a ring buffer in which "Events" are stored - that lets you not only see a single event that preceded the reset, but a whole sequence of events.

 

It has been mentioned a couple of times in the last few days

 

daniel123123123 wrote:
will watchdog reset clear that variable?

No.

 

However, you do need to ensure that the variable is not overwritten by the 'C' started code.

 

Exactly how you do that depends on your toolchain - but google "noinit" for starters ...

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

So we were both typing at the same time!

 

theusch wrote:
I don't know what good that address would do for you.  Log to EEPROM for later readout and analysis?

Maybe set a breakpoint in the ISR; when it's hit, use the debugger to investigate ...

Last Edited: Thu. Sep 14, 2017 - 04:13 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for the info guys

 

 

I'm using atmel studio 7 and MCU AT90USB647

 

 

I ended up creating 2 variables in the no init section

uint8_t watchdog_location __attribute__ ( ( section ( ".noinit" ) ) );
uint8_t watchdog_location_copy __attribute__ ( ( section ( ".noinit" ) ) );

 

in various parts of program I might assign "watchdogLocation" to 1, 2, 3, ...

 

on startup in init3 section I make a copy

uint8_t MCUSR_copy __attribute__ ( ( section ( ".noinit" ) ) );
void get_mcusr ( void ) __attribute__ ( ( naked ) ) __attribute__ ( ( section ( ".init3" ) ) );
void get_mcusr ( void )
{
	MCUSR_copy = MCUSR;
	MCUSR = 0;
	wdt_disable();

	if ( BIT_TST ( MCUSR_copy, WDRF ) )
		watchdog_location_copy = watchdog_location;
	else
		watchdog_location_copy = 0;
}

 

then early in my program I send "watchdog_location_copy" to terminal

 

seems to work

 

 

slightly different topic by I noticed that "Naggy" complains about

MCUSR_copy = MCUSR;

Severity Code Description Project File Line

Error [N] 2465 : non-ASM statement in naked function is not supported

 

I think it was ok with atmel studio 6.x

 

 

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

daniel123123123 wrote:
non-ASM statement in naked function is not supported

So don't declare it as naked, then!

 

EDIT

 

https://gcc.gnu.org/onlinedocs/gcc/AVR-Function-Attributes.html

 

EDIT 2

 

Specifically, it says:

While using extended asm or a mixture of basic asm and C code may appear to work, they cannot be depended upon to work reliably and are not supported.

 

Last Edited: Thu. Sep 14, 2017 - 04:41 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

daniel123123123 wrote:
in various parts of program I might assign "watchdogLocation" to 1, 2, 3, ...

So, how does that help you when your code runs amok and starts executing data?  Or your ISR never returns?  Or (e.g. heavy noise spikes) interrupts fail to be honored.  Or "restore factory defaults" from EEPROM now takes twice as long to update all needed bytes?

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

this is what is recommended from "avr/wdt.h"

 

    #include <stdint.h>
    #include <avr/wdt.h>

    uint8_t mcusr_mirror __attribute__ ((section (".noinit")));

    void get_mcusr(void) \
      __attribute__((naked)) \
      __attribute__((section(".init3")));
    void get_mcusr(void)
    {
      mcusr_mirror = MCUSR;
      MCUSR = 0;
      wdt_disable();
    }

 

 

I can also set watchdogLocation to different values in various ISRs, so if it dont return then the value will be preserved on WD reset