I wrote a generic avr program wrapper which already use the watchdog timer to restart - and after the watchdog reset - recover the the bad situation.
After this recover process i have to restart the avr. Everything i've found in topic "software reset arduino" is about to set the shortest watchdog (15ms) timeout, then spins the CPU (for(;;);) until it cause watchdog reset.
But this results to enter the recovery process which is already done in this point.
It is any elegant way to achieve this?
Some non or less elegant way:
I can bind a digital pin to the reset and pull up with a resistor.
I can write to a fixed address in the flash or eeprom (but this maybe happens frequently) before soft restart, to prevent entering to recovery mode.
Is there any register that "survives" soft resets?
Edit:
I add mock example code to hint what i trying to do.
In the actual code, in the recovering the microcontroller connect to the serial bus, waits for commands then resets itselft in oder to return to application mode.
/*************************** Application wrapper ******************************/
//define call_application and call_recover as weak empty functions
//so they can be rewritten.
bool isWatchdogReset()
{
return MCUSR == 8;
}
void softwareReset()
{
// wdt_enable(WDTO_15MS);for(;;);// (this way enters recovery mode)
//or
// asm ("jmp 0x0");// (this way function registers not being resetted)
}
bool isSoftwareReset()
{
//???
}
int main()
{
bool needRecover = isWatchdogReset() && !isSoftwareReset();
MCUSR = 0;
init_board();
wdt_enable(WDTO_1S);
while(1)
{
if(!needRecover)
{
call_application();
}
else
{
call_recover();
}
wdt_reset();
}
}
/********************************* Application ********************************/
void call_application()
{
if(randomTrue())
{
//stuck more that 1 secounds, that results WDT reset
}
else
{
//proper operation
}
}
/********************************** Recover ***********************************/
void call_recover()
{
//initialize UART, attach interrupts, Write flash and EEPROM, modify
//function registers.
//recovering completed, returning to the original application as like
//nothing's happened.
softwareReset();
}
Edit: I try explain short to spot the point:
1) I already use the watchdog timer to detect when the application code is flawed.
2) soft reset is an inproper solution, because it doesn't reset the registers. So onyl the program will be resetted, the state of the microcontroller doesn't.
3) To commit a proper reset, the solution is to timeout the watchdog timer. But see point 1), it is already used, so how can you make the difference of a requested reset and a flawed code recovery reset?