unknown cause of reset w/ WDT enabled

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

I have a mega32 with a .5 s WDT. It had been working fine and then out of the blue it starts hanging (for a short period of time; i.e. it hangs then goes back to work). This only occurs when the WDT is enabled. When the WDT is disabled I don't have any problems with resets or hangs.

The mega also seems to be resetting itself during this. I used the AVRStudio debugger to try and analize the problem. My watchdog reset function isn't causing the WDT trigger reset, which is why I suspect code hang. But looking at MCUCSR on reset at the top of main() to figure out the source of reset shows MCUCSR to be 0x00. Or am I misunderstanding the meaning of that register?

Additionally, there is a second device which notices when the problem device goes unresponsive. It will notice this before the WDT triggers a reset. However, if the problem were due to a code hang and WDT reset, I would expect the second device to notice the problem when the WDT is disabled; but that isn't the case.

My program is interrupt driven and has an emptly infinite loop in main(). As a test I stuck a WDR call in that loop. The mega32 went much longer without hanging, but still hung.

Any thoughts or ideas? Does anyone know of a code analysis tool for the ATmegas/CodeVision/AVRStudio to analyze how long sections of code run, or where they hang? How might enabling a WDT cause a reset if the WDT isn't doing the resetting?

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

It is probably spending more time between watchdog strobes than you expect.

This can be difficult to debug and the simulator does not help much. Try putting an extra strobe in somewhere that you think might be occupying some time. If no change, then remove it and try somewhere else. This will take some effort and it is NOT guaranteed to produce understandable results.

With a hardware emulator, you can do a "trace record" to see where it came from prior to the interrupt. Alas, I don't think you can do this with "modern" debugging.

Jim

 

Until Black Lives Matter, we do not have "All Lives Matter"!

 

 

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

How are you reading MCUCSR? More specifically, how is the contents of that registered displayed to you? Over the UART? LEDs? You said you are using the AVRStudio "debugger." Is that the simulator? JTAG-ICE?

MCUCSR should never be 0 unless you specifically set it to 0. Try outputing the contents of MCUCSR to one of the 8-bit ports and then disable the watchdog timer and sit in a loop.

PORTB = MCUCSR
disable watchdog timer
while(1) // loop forever

Once you see a sane value (anything but 0), change the code to only sit in the loop if you see a specific reset condition (WDRF).

if WDRF in MCUCSR is set
     PORTB = MCUCSR
     disable watchdog timer
     while(1)
end if

Do not perform an 8-bit comparison on MCUCSR ie. if(MCUCSR == (1<<WDRF)) because multiple flags can be set.

/* John Butera */

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

It does look like a watchdog reset occurs.
If you have an oscilloscope you can toggle an output at each Watchdog strobe. If it actually takes longer you will have to figure out which part of your main loop is causing it.
Remember that your whole main loop will go slower if you have a lot of interrupt activity

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

Thanks for all the help, I'll see what I can figure out.

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

Turned out it was a memory problem. The data stack size was 50 byte and CodeVisionAVR said I was using 45 bytes. I doubled the data stack to 100 bytes and the problem went away.

I've run into this issue several times: CodeVision says I still have some free data stack or global memory space and it turns out I really don't. Has anyone else had this problem with CodeVision?

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

It is not a "problem". CV estimates the data stack size by looking at the deepest nesting level in a "normal" path through the code. Your application may not follow the same path.

Are you sure that "CodeVisionAVR said I was using 45 bytes"? My compiler says

Quote:
Estimated Data Stack usage:

You may have recursion, nested interrupts, local variables within code blocks, large numbers of parameters to functions like printf(), calling functions via pointers, etc. Or you may be flat-out overrunning a stack-based variable such as a buffer, and increasing the stack size may make the effects benign. From your app description (no work in the main loop) I'm guessing you nest interrupts.

If you have a fairly vanilla C app, it may be worth your time to do some stack dumping and see why the estimate is exceeded.

Lee

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

good points. thanks Lee. Nested interrupts is probably the issue. How did you know how CV estimates the data stack usage? I saw no mention of that or how their estimate might be incorrect in their documentation.

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

pgasper wrote:

How did you know how CV estimates the data stack usage? I saw no mention of that or how their estimate might be incorrect in their documentation.

I don't remember. It was probably either a release note when the line was added to the compilation summary, or the answer to a query on CV's Yahoo message board.

But it's just kind of standard stuff. A compiler can't know the program flow beyond a certain point in C. Any use of function pointers is one example; any recursion is another. Now >>you<< as the app designer may have all the factors under control so that the stack doesn't run away, but the compiler cannot know that.

Anyway, I would again suggest that you instrument your app in some way. Either an ICE, or a simple memory dump function. [Note that a very simple SRAM dump gives you the registers, I/O space, and SRAM space since they are in one memory map.] Run your app under "normal" & "max" conditions, and see how far your stack grew. Alternatively you can have your app sample periodically if you have some kind of "stack end markers". Note that it is not sufficient to just look at the stack pointer value(s); the stack may have grown and contracted dramatically between checks.

Lee

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.