User Tools

Site Tools


tutorials:library:arduino:bootloader.html

Bootloader for Atmega328

Here is the package for a 'fixed up' ATmega328 bootloader. To program it you may need to change the Makefile's ISPTOOL, etc definitions. The commands are make adaboot328; make TARGET=adaboot328 isp328 (I couldn't get the default 'isp' target to work so I made a new one)

This version has a few fixes: first it integrates the 'no-wait' and 'no-hang' fixes below. It also fixes the annoying "missing signature bytes" bug that freaks out avrdude when programming without the IDE. I also repaired the EEPROM code so that now you can upload and download the EEPROM memory as well as flash. Finally, theres a 'upload feedback' using the LED, for arduino clones that don't have TX/RX leds

Please note that the fuses are different for this chip because of the extended memory!

"No-Wait" bootloader

Here's a bootloader hack that will automatically start the sketch after it has been uploaded and will also only start the bootloader when the reset button is pressed (so when you plug in power it will go straight to the sketch)

Add the bold lines to bootloader firmware, as shown

/* 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(EXTRF))) // if its a not an external reset...
      app_start();  // skip bootloader</strong>
 
    /* set pin direction for bootloader pin and enable pullup */
    /* for ATmega128, two pins need to be initialized */

Then add the bold text later on, as shown:

	/* Leave programming mode  */
	else if(ch=='Q') {
	  nothing_response();
 
	  // autoreset via watchdog (sneaky!)
	  WDTCSR = _BV(WDE);
	  while (1); // 16 ms</strong>
	}
	/* Erase device, don't care as we will erase one page at a time anyway.  */
	else if(ch=='R') {
	    nothing_response();
	}

You can also just grab the source code and compiled hex file here.

It will work in NG or Diecimila Arduinos

No-hang bootloader

If you are using a Diecimila with auto-reset you may be frustrated when your communications program accidentally triggers the bootloader. Here is a quick hack to make the bootloader quit if it doesn't receive a '0' character first (which would indicate the Arduino software is trying to talk to it.

Add the following lines

/* main program starts here */
int main(void)
{
    uint8_t ch,ch2;
    uint16_t w;
    uint8_t firstchar = 0;
 
	.....
 
	/* Hello is anyone home ? */ 
	if(ch=='0') {
	  firstchar = 1; // we got an appropriate bootloader instruction
	  nothing_response();
	}else if (firstchar == 0) {
	  // the first character we got is not '0', lets bail!
	  // autoreset via watchdog (sneaky!)
	  WDTCSR = _BV(WDE);
	  while (1); // 16 ms
	}


You can also just replace the last two lines with app_start()

Upload sketches with AVRDUDE

The bootloader is an 'stk500'-compatible, which means you can use good ol' AVRDUDE to program the arduino.

Just plug in the USB cable, then press the reset just before you start avrdude. If you need an avrdude tutorial, check out this page

  • Use -b 19200 to set the baud rate to 19200
  • The device signature reads dont seem to work so you'll want to use -F
  • The programmer type is avrisp
  • The device type is -p m168
  • The port is whatever the FTDI chip shows up as

/home/ladyada/public_html/wiki/data/pages/tutorials/library/arduino/bootloader.html.txt · Last modified: 2016/01/28 18:05 (external edit)