Bootloader hack: Auto-start app after upload

Ever find yourself wasting SECONDS of your life waiting for the arduino to 'reset' after you upload a new sketch
and then you also have to wait SECONDS for the app to start?
NO MORE!

this quick hack will automatically reset the arduino after uploading and skip the bootloader. To get back into the bootloader, just press the reset button (or use the diecimila 'auto-reset' capability). This hack uses the watchdog timer and MCU status register to figure out how the chip was reset

in main(), change the begining of the code to:

/* main program starts here */
int main(void)
{
    uint8_t ch,ch2;
    uint16_t w;

    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(WDRF)) // if its a watchdog reset...
      app_start();  // skip bootloader

    /* set pin direction for bootloader pin and enable pullup */
    /* for ATmega128, two pins need to be initialized */

then change the 'Q' command later on...

      /* Leave programming mode  */
      else if(ch=='Q') {
        nothing_response();

        // autoreset via watchdog (sneaky!)
        WDTCSR = _BV(WDE);
        while (1); // 16 ms
      }

I may be confused because I just woke up, but why not just call app_start() from within the Q command? Are you planning to trigger the watchdog reset in other ways?

I may be confused because I just woke up, but why not just call app_start() from within the Q command? Are you planning to trigger the watchdog reset in other ways?

you totally can but i like to use the WDT because its very 'clean': you know that when you reset you have a fresh slate so that no matter what the bootloader did it will not have any funky registers set when the program runs.

also... you can do this

    // 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

which -only- bootloads on external reset. This means that if the power flickrs it will also not start the bootloader. might be a nice safety precaution: if the arduino is 'doing something' and the power turns off and then back on it wont accidentally go into the bootloader (if there's serial data being sent to it)

also...you could use the watchdog timer to get the micro out of the bootloader as it is a natural way to 'timeout'..instead of doing all that MAXERRORCOUNT/MAXTIMECOUNT stuff :slight_smile:

Please excuse my superficiality for this question. I look at the bootloader code and I see this line:

        // autoreset via watchdog (sneaky!)
        WDTCSR = _BV(WDE);
        while (1); // 16 ms

My first reaction is to use this method in a sketch for the purpose of a reset. Well, it does not reset (it just stays in the infinite loop). Any ideas/explanations?
Thank you.
FlorinC

PS Why is it "sneaky"?

My first reaction is to use this method in a sketch for the purpose of a reset.

Apparently, this isn't a good way to reset an Arduino. Others have written a better description than I ever could. Hopefully some time digging through the forum will help...

http://www.google.com/search?q=reset+watchdog+site%3Aarduino.cc%2Fcgi-bin%2Fyabb2%2FYaBB.pl

Any ideas/explanations?

This seems to work on a Teensy (pin 6 has an LED attached)...

void setup( void )
{
  uint8_t ch;
  
  pinMode( 6, OUTPUT );
  
  ch = MCUSR;    
  MCUSR = 0;
  WDTCSR |= _BV(WDCE) | _BV(WDE);
  WDTCSR = 0; 
    
  if (ch & _BV(WDRF)) // if its a watchdog reset...
  {
    digitalWrite( 6, LOW );
  }
  else
  {
    WDTCSR = _BV(WDE);
    digitalWrite( 6, HIGH );
  }
}

void loop( void ){}

PS Why is it "sneaky"?

Ladyada is using "sneaky" to mean sly or clever. It's a slang use of the word sneaky.

Good luck and I'm sorry I can't be more helpful,
Brian

Thanks.
It started to make sense after I read another related thread:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1234876699
I will try the "Teensy" method later today.
I don't feel like burning another bootloader for this purpose. Anyway, for my purpose (reset by XBee), there is already a workaround that I need to try (the one described by ladyada, hacking the XBee board).

Coding Badly,
Your piece of code shows exactly the same behaviour.
So I conclude that "self reset" is not a real option in a sketch (it works in the bootloader for the reasons stated in the article I pointed to previously, if I remember correctly).
Time for the workaround.

I tried a few things I thought might overcome the problem but I just couldn't get it to work.

Good luck,
Brian