Go Down

Topic: Software reset on new Arduino's possible or not? (Read 1 time) previous topic - next topic

JO3RI

I have been reading about the possibility of resetting your arduino trough the sketch itself. Some say it's not possible others say it can be done.

Now for the newer Arduino  duemilanove, uno and ethernet, I would say, you can, if you connect a capacitor from a digital pin to the reset pin. In your sketch you'll only have to put that same pin to high.

Is this correct?

This would help in projects where you can setup things like IP, MASK, MAC, ... other setup decisions and need the arduino to reboot for using the new setup values.

PS: doesn't the arduino reset when you open the Serial Monitor or when you upload a sketch?
http://www.JO3RI.be

Nederlandstalige sectie - http://arduino.cc/forum/index.php/board,77.0.html -

spirilis

Yes, in fact, if you look at the bootloader source code, the "reset" is simple; just start executing at address 0x0000:

(viewing /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/bootloaders/atmega/ATmegaBOOT_168.c on my Mac)

Code: [Select]

void (*app_start)(void) = 0x0000;

^ that defines a function pointer "app_start()" whose location goes to 0x0000

Code: [Select]

#ifdef WATCHDOG_MODS
       ch = MCUSR;
       MCUSR = 0;

       WDTCSR |= _BV(WDCE) | _BV(WDE);
       WDTCSR = 0;

       // Check if the WDT was used to reset, in which case we dont bootload and skip straight to the code. woot.
       if (! (ch &  _BV(EXTRF))) // if its a not an external reset...
               app_start();  // skip bootloader
#else


just running app_start(); will then jump to the first instruction in Flash.  At that point your sketch's compiled hex code should re-setup all its data, stack pointers, etc.

Note: I'm not sure if that resets the state of all the I/O registers though, so it might not be as clean as a true hardware reset...

JO3RI

Mmm, I just realized that my own solution is a hardware reset invoked by software  :D

Your solution is actually a software reset, now I'll have to test that one out. Not sure it will be enough to just  jump to the first instruction in Flash, but there's only one way to find out.
http://www.JO3RI.be

Nederlandstalige sectie - http://arduino.cc/forum/index.php/board,77.0.html -

Graynomad

Jumping to 0 works fine, technically it's not the same but I doubt there's any practical difference.

I use

asm ("jmp 0");

but there was a different approach posted somewhere yesterday with a pointer to a function defined to be at 0.

______
Rob
 
Rob Gray aka the GRAYnomad www.robgray.com

AWOL

Quote
but there was a different approach posted somewhere yesterday with a pointer to a function defined to be at 0.

I just lifted it straight from the bootloader source.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Grumpy_Mike

Quote
In your sketch you'll only have to put that same pin to high.

Is this correct?

No it is not. This is because the pin gets set to an input part way through the reset process and so the reset is not completed. The data sheet warns against this.
Jumping to the reset vector will not do everything a hardware reset will. While it will start the program again it will not reset the I/O pins or other things to the default state.
One way of getting a true reset is to have a pin trigger a monostable like an NE555 or 74LS121 (or 74LS123) and have the output of the monostable drive the reset pin. That way you can ensure the full time on the reset pin.

dc42

If my reading of the datasheet is correct, another way to do a full reset from software would be to enable the watchdog timer with its minimum timeout of 16ms and watchdog reset enabled. Then just sit in a loop forever - it will time out and reset after 16ms.
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

dc42

#7
Sep 07, 2011, 05:46 pm Last Edit: Sep 07, 2011, 06:15 pm by dc42 Reason: 1
.. just tried using the watchdog to do a hardware reset and it works. Just do this to cause a reset:

  noInterrupts();
  WDTCSR = 0x98;
  for(;;){}

[EDIT: on further invstigation, the following is better because it guarantees to set the watchdog time to the minimum of 16ms:

  noInterrupts();
  __asm("wdr");
  WDTCSR = (1<<WDCE) | (1<<WDE);
  WDTCSR = (1<<WDE);
  for(;;){}

]

Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

Graynomad

Yep, that should work, something like

WDTCSR = (1<<WDE);
while (1);

IIRC.

______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

Grumpy_Mike

The problem with the watch dog is that if you set it too short you will never get program to run in the first place because the boot loader takes a bit seeing if there is a download ready.

There have been instances of people bricking their arduino doing this and only disabling the watchdog by reprogramming the fuses have they been recovered. Of course no problem if you have a programmer but a pain if you have not.

dc42


The problem with the watch dog is that if you set it too short you will never get program to run in the first place because the boot loader takes a bit seeing if there is a download ready.

There have been instances of people bricking their arduino doing this and only disabling the watchdog by reprogramming the fuses have they been recovered. Of course no problem if you have a programmer but a pain if you have not.


It works fine for me on an Arduino Uno when I set the watchdog timeout to the minimum value of 16ms. I note that the optiboot bootloader initialises the watchdog very early on. Possibly there could be a problem if there are other bootloaders that don't re-initialise or disable the watchdog.
Formal verification of safety-critical software, software development, and electronic design and prototyping. See http://www.eschertech.com. Please do not ask for unpaid help via PM, use the forum.

retrolefty

Quote
It works fine for me on an Arduino Uno when I set the watchdog timeout to the minimum value of 16ms. I note that the optiboot bootloader initialises the watchdog very early on. Possibly there could be a problem if there are other bootloaders that don't re-initialise or disable the watchdog.


That was the problem with the original 'arduino' bootloader and many of it's decendents, the WDT interrupt would just keep the bootloader from timing out and jumping to the sketch code. I think Lady Ada was the first to offer a arduino compatible bootloader which handles the WDT correctly and that same method of handling WDT then applied to the uno bootloader. I don't have a list of which bootloaders don't handle WDT correctly.

Lefty

JO3RI

Quote
One way of getting a true reset is to have a pin trigger a monostable like an NE555 or 74LS121 (or 74LS123) and have the output of the monostable drive the reset pin. That way you can ensure the full time on the reset pin.


but is a capacitor not able to feed the reset pin the full time needed to get a hard reset?
http://www.JO3RI.be

Nederlandstalige sectie - http://arduino.cc/forum/index.php/board,77.0.html -

Grumpy_Mike

Quote
but is a capacitor not able to feed the reset pin the full time needed to get a hard reset?

No.

JO3RI

Quote
Quote
but is a capacitor not able to feed the reset pin the full time needed to get a hard reset?

No.


I don't understand why, but I accept that.

This code from dc42 works for me on my Arduino Ethernet, but I do think (pretty sure) void setup (){} isn't executed again

Code: [Select]

void reset(){
  noInterrupts();
  __asm("wdr");
  WDTCSR = (1<<WDCE) | (1<<WDE);
  WDTCSR = (1<<WDE);
  for(;;){};
}
http://www.JO3RI.be

Nederlandstalige sectie - http://arduino.cc/forum/index.php/board,77.0.html -

Go Up