Go Down

Topic: Bootloader hack: Auto-start app after upload (Read 1 time) previous topic - next topic

ladyada

Sep 08, 2007, 08:20 am Last Edit: Sep 08, 2007, 08:24 am by ladyada Reason: 1
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
     }

mellis

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?  

ladyada

#2
Sep 08, 2007, 03:47 pm Last Edit: Sep 08, 2007, 03:55 pm by ladyada Reason: 1
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 :)

florinc

#3
Jun 16, 2009, 02:53 pm Last Edit: Jun 16, 2009, 02:55 pm by florinc Reason: 1
Please excuse my superficiality for this question. I look at the bootloader code and I see this line:
Code: [Select]
       // 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"?


Coding Badly

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: [Select]

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

florinc

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

florinc

#6
Jun 19, 2009, 03:35 am Last Edit: Jun 19, 2009, 03:10 pm by florinc Reason: 1
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.

Coding Badly

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

Good luck,
Brian

Go Up
 

Quick Reply

With Quick-Reply you can write a post when viewing a topic without loading a new page. You can still use bulletin board code and smileys as you would in a normal post.

Warning: this topic has not been posted in for at least 120 days.
Unless you're sure you want to reply, please consider starting a new topic.

Note: this post will not display until it's been approved by a moderator.
Name:
Email:

shortcuts: alt+s submit/post or alt+p preview