Question

The short story:

What are those reset conditions, which will not set a bit in MCUSR of an ATmega processor, but still cause a reset?

The long story:

I use brown-out detection in an ATmega168 and have a place in my code to handle it. If my system loses power, a capacitor keeps it above brown-out level for around a half second, and when I restore power, the brown-out handling routine successfully runs. (I check the brown-out bit in the MCUSR.)

However, when I slowly decrease voltage on the system, and slowly give it back, the processor restarts, and the brown-out handling routine does not run: the MCUSR is zero!!! (I use an external debugger through DebugWire to check it.)

What can cause this? If it were something else, like the watchdog being accidentally enabled (I don't use it, and disable it at startup), there would be at least something in the MCUSR.

But no, it was neither a Watchdog reset (bit 3), a brown-out reset (bit 2), external reset (bit 1), or power-on reset (bit 0), so what did cause the reset if neither of the above??

Another strange thing: after such a condition, a reset will, in some cases, periodically occur, always with a value of zero in MCUSR.

Otherwise, when this does not happen, the system runs always perfectly.

Edit:

I couldn't find a conclusive answer elsewhere, what kind of reset does a stack overflow, or similar software-related error lead to? Maybe those are the conditions which might reset the processor, and leave the MCUSR alone? I thought such conditions just corrupt the RAM or maybe even the Program Counter, but don't cause a reset.

Was it helpful?

Solution

A stack overflow does not cause a reset. A stack overflow is purely a software condition, which will likely lead to undefined behavior. There are many, many symptoms that could result from a stack overflow. For example:

  1. No apparent change in behavior
  2. Corruption of adjacent memory leads to unexpected or undefined behavior such as deferencing a null pointer or executing invalid instructions

A stack overflow might appear to cause a reset if the processor executes an invalid instruction and the exception is unhandled. This again is software-defined behavior depending on the software exception handler. The same thing can happen with dereferencing a NULL pointer, or pointer to invalid memory space.

You may want to double check that there aren't additional registers that may specify reason for the reset as well.

You mentioned that you lower the voltage and then raise it. Does it go into reset if you simply lower the voltage? Do you have code that is monitoring the voltage? I wonder why you suspect a software condition bug as the cause when you are changing the hardware conditions.

OTHER TIPS

Have you tried playing with BODLEVEL fuse if it makes any difference?

However, this could be easily caused by stack overflow or some other software issue. Especially if you are working with function pointers - it can be just a jump to 0. I had such problems in the past.

Never really did that, but I believe you could easily distinguish between reset and 'jump' if you check the value of some other register that you changed in your software. If it really was a reset registers should be reinitialized too. E.g. set PORTB to 0x55 somewhere in your code. Then on boot check its value. If it was a reset it should be 0x00, if not it should remain 0x55.

If you use avrgcc try this:

volatile char mcusr __attribute__ ((section (".noinit")));
void main(void){
  mcusr=MCUSR;
  ...
  if(mcusr&0x01)printf("WD");
  if(mcusr&0x02)printf("EX");
  if(mcusr&0x04)printf("BO");
  if(mcusr&0x08)printf("PO");
  ...
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top