Software Reset WITH Bootloader

I am trying to accomplish a reset of the arduino using a watchdog timeout that allows it to return to the bootloader to be programmed. However the over arching objective is simply to be able to reset the device and re initiate the bootloader via serial command. A lot of the challenge with this is that I don't think I am asking the correct questions, or using the right terminology to search for it. I have an UNO running the version of optiboot shipped with Arduino 1.5. Thank you in advance to anyone that answers this.

What exactly are you envisioning? Obviously you don’t want to upload sketches via the arduino IDE, since it already performs a reset to enter the bootloader. You do want to upload sketches wirelessly or something?
If you do, let me know, i’ve done exactly that (Bluetooth).

Entering the bootloader using a watchdog timeout is easy, include the wdt.h file on the top of your sketch

 #include <avr/wdt.h>

then you can use something like this to enter the bootloader on recieving a specific character.

if(Serial.available())       
  {
    char = Serial.read();   
    
    if( char== '#' )               
    {
         wdt_enable(WDTO_30MS);
         while(1) {};
    }
}

That is exactly what I am doing. Upload with bluetooth. I have implemented the sketch above but it doesn't seem to re-enter the bootloader. I wrote a program that will send the reset command and then immediately start avrdude to upload. let me try this again. and post my results.

It probably does enter the bootloader but it exits is immediately because optiboot is programmed to start your sketch on a watchdog timeout. to have enough time to upload my sketch via bluetooth i have edited the bootloader so that it will not start the sketch unless instructed to so. To do this i have commented out the code that enabled the watchdog in the bootloader. However, without further changes the sketch won't ever start automatically anymore on powerup. Normally optiboot starts the sketch when the reset is the cause of a watchdog timeout. I've made further changes so it does the opposite. So it stays in bootloader when a watchdog timeout occured.

Naturally this comes with the price of not being able to use the watchdog reset in your sketch for anything other then entering the bootloader. But for my situation this was fine. With all the changes the bootloader still fits in a 512 byte block. Since i don't use avrdude for the programming (I use Android) i could delete some of the code in the bootloader needed to make avrdude happy. So for you such changes will likely increase the bootloaders size to over 512 Bytes.

That would likely be fine for my situation as well. in the optiboot I tried commenting out the no wait adaboot mod like this:

#ifdef __AVR_ATmega8__
  SP=RAMEND;  // This is done by hardware reset
#endif

  // Adaboot no-wait mod
  //ch = MCUSR;
  //MCUSR = 0;
  //if (!(ch & _BV(EXTRF))) appStart();

but it just keeps rebooting, optiboot does not seem to use wdt_enable per this comment

// We don't use <avr/wdt.h> as those routines have interrupt overhead we don't need.

So which portion of the boot loader do I need to comment out?

Yeah it’s a bit tricky to get the bootloader functioning correctly since it also uses the watchdog reset to start the app.

I’ll link you my optiboot code. don’t use it as is since its build for my specific application. I have removed some functions needed for Avrdude, and added readout protection (at least 19660 bytes need to be written in order to read back the sketch/binary) also
Also added some untested code to be able to use the watchdog reset for other purposes aswell (reading digital value of output pin from another device, if HIGH it enters programming mode, otherwise it starts the application)

I’ve added comments to a couple of commented lines which you should uncomment. see the attachment below.
Compare the original with the one i use and make the needed adjustments. good luck.

optiboot.c (24.6 KB)

Ok so I have been mucking with the boot loader now all day and I cannot see a way to get the bootloader to re initiate with the watchdog. I am going insane here. I tried setting eeprom as a flag but then the bootloader wouldn’t burn onto the chip. I am continuing to chip away at the problem.

This is what I tried most recently

// Adaboot no-wait mod
  ch = MCUSR;
  MCUSR = 0;
  
  uint8_t  byteRead = eeprom_read_byte((uint8_t*)23); 
  uint8_t  specialCircumstances = 0;
  if(byteRead == 69){
	if((ch & _BV(WDRF))){
		eeprom_write_byte ((uint8_t*) 23, 0);
		specialCircumstances = 1;
	}
  }
  if (!(ch & _BV(EXTRF))&& specialCircumstances < 1) appStart();

First thing you need to realize is that coding a bootloader is not the same as writing a sketch for the arduino. to save space the bootloader will not have access to any of the arduino libraries, it's just pure C++ with direct register manipulation. Using libraries will just bloat the bootloader to such an extent that it will not fit in the available bootloader space on the atmega328. So don't even try to use the eeprom arduino function. it won't work.

Second, Your making alterations that are not necessary. Try to use my code in attached in the previous post. To get the arduino to remain in bootloader mode all you have to do is comment out the below line in my optiboot.c example and compile it. if (!((PIND & 0x40) >> 6)) appStart();

the remaining line:

  if (!(ch & _BV(WDRF))) appStart();

Tells to start the main program only if the reset was NOT caused by a watchdog reset, if a watchdog reset did occur the arduino will just remain in bootloader mode until the instruction to leave programming mode is given.

It won't yet work for uploading sketches via avrdude, but it least it will get you one step closer while i catch-up on some needed sleep.In the mean time, try to get grip on how the optiboot bootloader works. It's important to understand the code before you attempt to make changes.

I’ve removed all my application specific stuff from the optiboot.c file. Attached is a clean optiboot.c and hex file(hex file compiled for a baudrate of 38400).
The bootloader is only triggered on a watchdog reset. To exit the bootloader and start the main application the STK_LEAVE_PROGMODE command needs to be issued.

Good thing to note is optiboot also starts the main application when an invalid command/character is recieved on the UART. This is to prevent avrdude and the bootloader from getting out of sync. So only send valid STK500 commands otherwise the bootloader will just start the main application.

optiboot_atmega328.hex (1.44 KB)

optiboot.c (24.7 KB)

Hi all,

I want to upload my mega2560 on UART "RX/TX" with Avrdude from another board I send at the begining reset, and after this command :

avrdude -V -F -p m2560 -c wiring -b 115200 -Uflash:w:/config/Pgm.hex -P /dev/ttyS1

But it does not work!!

I tried with USB port for both Arduino and CubieBoard, and the command is :

avrdude -V -F -p m2560 -c wiring -b 115200 -Uflash:w:/blink/Pgm.hex -P/dev/ttyACM0

And it works fine!!

Can you help me please!! I must upload my arduino on UART!!

I found the solution!!

It is ok!

I need to put reset before and the correct command line is : avrdude -V -F -D -p m2560 -c stk500v2 -b 115200 -Uflash:w:/Pgm.hex -P /dev/ttyS1

Thank you

After searching for a long while, I found a way to start the bootloader from the program running on the Arduino. As this is one of the first posts to come up while googling for a solution to start the bootloader from the running program I am posting the solution here as well.

The github post

The test code

EDIT: The optiboot bootloader normally used by Arduino is an older version on which this trick does not work. The way to update the bootloader can be found here