Enabling watchdog timer system restart and waiting in a loop until reset is a legitimate way of SW resetting the µC as is using watchdog for catching µC's misbehavior which can be caused by various reasons.
However, some precautions have to be made when using watchdog system reset because on all AVRs that also have watchdog interrupt the watchdog with prescaler set to 0000 = 16 ms remains active after watchdog system reset condition. It is therefore responsibility of a programmer to clear MCUSR and to disable watchdog timer as soon as possible after occurrence of such a condition. Since LPM routines for initializing .data and .bss sections can last longer than watchdog timeout interval, the code for disabling the watchdog must be placed in .init3 section and the contents of MCUSR can optionally be saved for later reset source examination. Here is the code that does the described:
uint8_t mcusr_copy __attribute__ ((section (".noinit")));
void disable_wdt(void) \
__attribute__((naked)) \
__attribute__((section(".init3")));
void disable_wdt(void) {
mcusr_copy = MCUSR;
MCUSR = 0x00;
wdt_disable();
}
However, the problem may arise when using a bootloader which does not account for the possibility of watchdog system reset condition. If that is the case, watchdog timeout will happen inside bootloader (which is executed the first) before the above code will have the chance to disable the watchdog timer and µC will be stuck in an endless reset loop. Since reseting the µC will not clear WDRF flag in MCUSR register (it can be cleared only in software or by Power-on reset) the only way will then be to cycle the power and upload a new code when watchdog timer is still not activated by previous code. WDRF in MCUSR register must be cleared before wdt_disable()
because WDE can not be cleared if WDRF is still set - therefore the order of the instrucions in the above code is very important. The function placed in .init3 section must not be called from later code.