Pages: [1]   Go Down
Author Topic: Software reset on new Arduino's possible or not?  (Read 1418 times)
0 Members and 1 Guest are viewing this topic.
Hamme, Belgium
Offline Offline
Sr. Member
****
Karma: 4
Posts: 386
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged


Maryland, USA
Offline Offline
Full Member
***
Karma: 0
Posts: 162
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
void (*app_start)(void) = 0x0000;
^ that defines a function pointer "app_start()" whose location goes to 0x0000

Code:
#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...
Logged

Hamme, Belgium
Offline Offline
Sr. Member
****
Karma: 4
Posts: 386
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Mmm, I just realized that my own solution is a hardware reset invoked by software  smiley-grin

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.
Logged


nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8475
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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
 
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 291
Posts: 25882
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

"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.

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 604
Posts: 33432
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 224
Posts: 6593
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

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.

United Kingdom
Offline Offline
Tesla Member
***
Karma: 224
Posts: 6593
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

.. 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(;;){}

]

« Last Edit: September 07, 2011, 11:15:19 am by dc42 » Logged

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.

nr Bundaberg, Australia
Offline Offline
Tesla Member
***
Karma: 126
Posts: 8475
Scattered showers my arse -- Noah, 2348BC.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yep, that should work, something like

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

IIRC.

______
Rob
Logged

Rob Gray aka the GRAYnomad www.robgray.com

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 604
Posts: 33432
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

United Kingdom
Offline Offline
Tesla Member
***
Karma: 224
Posts: 6593
Hofstadter's Law: It always takes longer than you expect, even when you take into account Hofstadter's Law.
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

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.

Left Coast, CA (USA)
Offline Offline
Brattain Member
*****
Karma: 361
Posts: 17263
Measurement changes behavior
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Hamme, Belgium
Offline Offline
Sr. Member
****
Karma: 4
Posts: 386
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged


Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 604
Posts: 33432
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Hamme, Belgium
Offline Offline
Sr. Member
****
Karma: 4
Posts: 386
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
void reset(){
  noInterrupts();
  __asm("wdr");
  WDTCSR = (1<<WDCE) | (1<<WDE);
  WDTCSR = (1<<WDE);
  for(;;){};
}
Logged


Pages: [1]   Go Up
Jump to: