Optiboot - improved Arduino bootloader

I've developed a new bootloader for 168 and 328 Arduinos. It has some nice features:

  • Faster upload speed.
  • Watchdog handling (Adaboot mods).
  • More sketch space - the bootloader is a quarter of the Arduino bootloader size, giving 1.5K of extra flash space.
  • Written in C, without large chunks of assembly.
  • Easy install.
  • Compatible with all 168 and 328 Arduinos.

Come and get it! Google Code Archive - Long-term storage for Google Code Project Hosting.

Heh... check out http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1270564546/0. I did mine Mar 19, you did your Apr 03. Before that no bootloaders were under source control! BTW, check out the poll... 58% of the people (not many so far) don't know what a code repo even is :-(. Bummer for us! Hope you don't mind if I dig into how you slimmed yours down and incorporate some changes! You are welcome to take my "pin 13 fades while waiting for DL" or my "double click reset for extra long DL" features if they will help you!

Here would be an interesting contest idea: The 512 byte bootloader contest (although Peter may have won it so far!).


It would be interesting, though, to see who could come up with the most functionality in a bootloader and keep it under 512 bytes. Could it be done in less? 256 bytes...?

Kinda like the "intro" competitions you see demo coders do; maybe get some Arduino vendors to donate prizes...


vxir: Have a look at the hardware directory installation method. It's a recent feature (Arduino 18), but it is very beginner friendly. Unfortunately the bootloader is very tight in there - I think there are only 4 bytes free, so I won't be adding much extra functionality soon. I was pondering switching to 250kbaud, once the Arduino distribution includes the latest Avrdude which supports non-standard baud rates.

cr0sh: There isn't much point in going below 512 bytes. On the ATmega328, the smallest boot block you can have is 512 bytes, so if you go smaller you don't gain any extra program flash space. The next useful size on the 168 is 256 bytes - and I really don't think it would be possible to squeeze things that tight.

Hmm, I too like that idea.
Now I just need an AVR programmer to test this new bootloader… :stuck_out_tongue:


mowcius: You can use a second Arduino as a programmer: http://arduino.cc/en/Tutorial/ArduinoISP

There isn't much point in going below 512 bytes. On the ATmega328, the smallest boot block you can have is 512 bytes, so if you go smaller you don't gain any extra program flash space. The next useful size on the 168 is 256 bytes - and I really don't think it would be possible to squeeze things that tight.

Interesting thing to know; I wonder if a "bootloader developer FAQ" should be created...


Bootloader developer FAQ: Smart | Connected | Secure | Microchip Technology

(Which looks remarkably like the Atmel ATmega328P data sheet, by the way :wink: )

Great, thank you. I'll be trying this out as a bootloader but also using it to understand the source. Your code is MUCH easier to read than the standard because of all the conditional assembly for other processors. A couple of questions:

  1. Near the start of "main" you comment:
/* C zero initialises all global variables. However, that requires */
/* These definitions are NOT zero initialised, but that doesn't matter */
/* This allows us to drop the zero init code, saving us memory */

Is "C zero" something that you've removed? - I don't see it anywhere.

  1. Later you have a conditional assembly sequence:
#if 0
  // The compiler normally generates sts instructions for setting
  // up I/O space registers. But that takes 6 bytes per register.
  // This code can do it in 2, with an overhead of 20 bytes.
  // This starts to pay off when initialising 6 or more registers
  __asm__ volatile (
    "ldi r30,lo8(init_table)\n"
    "ldi r31,hi8(init_table)\n"
    [addr5]"i"(_SFR_MEM_ADDR(UBRR0L)), [val5]"i"((F_CPU + BAUD_RATE * 4L) / (BAUD_RATE * 8L) - 1)
  // Set up Timer 1 for timeout counter
  TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
  UCSR0A = _BV(U2X0); //Double speed mode USART0

I take it the #else block is used and not the #if 0?

  1. does the "adaboot mod" jump directly to the app on power on or unless reset is pressed?

  2. How long will the loader wait before giving up and running the app anyway if there's no host input and how is that controlled? Similarly, how does the loader know the input is done?

Thanks again for a highly readable module and i hope you don't mind the questions.

bill2009: Taking your questions in order.

  1. Maybe I should rephrase. "The language 'C' initialises to zero ...".
  2. Yes, the block of assembly language is not used. However, it took a lot of effort to write, and if one more register is initialised, it starts to save memory. So I've left it in the source code in case it becomes useful.
  3. Adaboot jumps straight to the application if a watchdog event has occurred. Adaboot is documented here: Arduino Hacks
  4. The bootloader jumps to the main app when getch() times out, after 500ms. It also jumps to the main app immediately on any bootloader protocol error, or when programming completes.
    Programming is complete when the bootloader receives the STK_LEAVE_PROGMODE message - but it must send acknowledgement before jumping to the main app.

mowcius: You can use a second Arduino as a programmer: http://arduino.cc/en/Tutorial/ArduinoISP

Yeah, had forgotten that as I have never tried it. Maybe I will try it then :slight_smile:


". . . bootloader for 168 and 328 . . ."

What about the 1280 (Arduino Mega)?

Well because it is a different type of chip, it would require another bootloader as far as understand it. The 168 and 328 are phsically identical with the same number of pins etc but the 1280 is completely different with 2 hardware serial ports and 54 I/O pins...


Vintage: The 1280 (Mega) requires changes to the codebase as many registers work in different ways. The intent was to publish once the majority of Arduinos were supported. However, I plan to extend support to the Mega at a later date.

Peter, thank you for this great bootloader!

Currently I am redesigning LumiNet and I think the biggest problem is that I use my own bootloader on the attiny chips...

I would love to see attiny support in the main distribution and a stk500-compatible bootloader is the missing link at the moment.

Maybe you can help? One problem with attinys is that they don't have a bootloader section... the other problem is that most of them don't have a U(S)ART. I appreciate all ideas and hints here or in the LumiNet Thread:

bohne: I had a go at implementing a software UART (AVR305) on Optiboot. I had to do another round of code trimming to make enough space, but it is now working. Optiboot should work with the ATmegatiny84 nicely once the memory and registers are remapped, and we test on real hardware.

Added bonus: With the new UART code, I can now upload to an Arduino at four times normal speed (230400 baud), the highest speed Avrdude supports on Arduino 18. Just knocked several more seconds off an ATmega328 programming cycle.

I'll be doing some reliability testing, but it looks like Optiboot just got a speed boost!

Nice [smiley=thumbsup.gif]

wow, really nice news!

Did you mean attiny84? Do you need hardware for the tests?

230400 baud sounds amazing.

I also used AVR305 on LumiNet. Implemented it in Assembler for different I/O pins. That was the reason why I needed .S file support in the official Arduino software (which was added in 0018).

Yup. I meant Tiny84. Unfortunately the software UART isn't the only hurdle. Also need to remap reset vectors so the bootloader can execute, and put safety code in to prevent the bootloader from erasing itself.

bohne: Throw me an email or personal message. Need to discuss some of the implementation details off-list.

And yes, 230k4 uploads are great. I've got a sketch that comes in at 28000 bytes. It uploads in 5.5 seconds, including verification. [smiley=grin.gif]

Peter, nice one.

Optiboot seems great for squeezing a little more code into those old 168 chips, it would be good if they had the benefit of the reduced upload time.

Any reason why the baud rate for the 168 chips is not taking advantage of the potential speed improvements?

mem: 168s were untested, hence not supported in Optiboot. Well, they weren’t… until just now.

I’ve just released Optiboot v2.

Main enhancements:
New soft-serial code giving accurate very high baud rates.
Duemilanove 328 uploads: up from 115200 to 230400 baud
Diecimila 168 uploads: up from 19200 to 230400 baud !!!
Speed enhancements to other platforms including Lilypad, Pros.

Check the download at http://optiboot.googlecode.com

(And yes, it still fits in 512 bytes. In fact it has 4 bytes spare!)