Pages: [1]   Go Down
Author Topic: Bootloader hack: Auto-start app after upload  (Read 1333 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Full Member
***
Karma: 0
Posts: 239
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
      }
« Last Edit: September 08, 2007, 01:24:48 am by ladyada » Logged

Forum Administrator
Cambridge, MA
Offline Offline
Faraday Member
*****
Karma: 12
Posts: 3538
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

0
Offline Offline
Full Member
***
Karma: 0
Posts: 239
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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 smiley
« Last Edit: September 08, 2007, 08:55:28 am by ladyada » Logged

0
Offline Offline
Edison Member
*
Karma: 8
Posts: 1411
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Please excuse my superficiality for this question. I look at the bootloader code and I see this line:
Code:
       // 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"?

« Last Edit: June 16, 2009, 07:55:34 am by florinc » Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 207
Posts: 12912
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
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


Quote
Any ideas/explanations?

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

Code:
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 ){}


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

0
Offline Offline
Edison Member
*
Karma: 8
Posts: 1411
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

0
Offline Offline
Edison Member
*
Karma: 8
Posts: 1411
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
« Last Edit: June 19, 2009, 08:10:52 am by florinc » Logged

Global Moderator
Dallas
Offline Offline
Shannon Member
*****
Karma: 207
Posts: 12912
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Good luck,
Brian
Logged

Pages: [1]   Go Up
Jump to: