Notes on the STK500 Serial Bootloader


Tips and Tricks for Bootloading and Programmer's Notepad


I found myself always fumbling when I needed to get a bootloader onto an ATmega for my personal projects. I'd always forget the settings, what little changes I had to make to each project, tweaks I had to add to the makefile, etc. So this is the culmination of tips and tricks using Programmer's Notepad and the stock Arduino bootloader.

  • Setting up basic hot keys in Programmer's Notepad
  • Displaying program code size after a compile
  • Improving the Arduino bootloader UART accuracy
  • Adding parallel programmer support to the Arduino/STK500 bootloader
  • How to get Programmer's Notepad to communicate with a serial bootloader

Hot Keys


It's simple: the shorter your programming cycle is, the more development you can get done. If it takes you more than 5-10 seconds to program a microcontroller, that's too long! So let's make it shorter.

Within Programmer's Notepad, you can setup a very neat shortcut. I found myself constantly clicking on the Tools->[WinAVR] Make All.

 http://www.sparkfun.com/tutorial/Notepad-Tips/ShortCut-1.jpg


Why not make a hot key?!

http://www.sparkfun.com/tutorial/Notepad-Tips/ShortCut-2.jpg


Click on Tools->Options

http://www.sparkfun.com/tutorial/Notepad-Tips/ShortCut-3.jpg


Scroll down to 'Tools'. Then drop the 'Scheme' box down and at the top of the list, select '(None - Global Tools)'. This will allow you to edit the items on the main 'Tools' drop down menu.

http://www.sparkfun.com/tutorial/Notepad-Tips/ShortCut-4.jpg


Double click on '[WinAVR] Make All'. You should see the window about. Here we can change what Programmer's Notepad does when we start this tool. The main point of this screen in the 'Shortcut:' box.

http://www.sparkfun.com/tutorial/Notepad-Tips/ShortCut-5.jpg

Notice I changed the name (because I like it that way) and set the shortcut to F5 (a hold over from my Sierra 'Save Game' days - ahh, I loved those text based adventure games). You can set the shortcut to whatever suits your fancy, but you're going to be using it a lot, so make it easy to get to. Click ok a few times to close everything out. Now, with a C program open, hit 'F5' and you should see the compiler run and spit out some information to the output window. All right!

http://www.sparkfun.com/tutorial/Notepad-Tips/ShortCut-6.jpg

You can also set shortcuts for programming. I prefer to set my program hot key to 'F9', a bit away from my compile button so that I don't accidentally hit it. Now with a C program open, and a programmer attached to your hardware you can simply hit F9 to flash your program onto your test board. These two shortcuts do wonders to cutting down small amounts of time to the programming cycle!



Code Size

<u2x0); enable="" the="" baud="" rate="" doubler="">
This is one of my favorite tricks. </u2x0);>Somewhere on the internet (I think it was Ryan who originally found this trick) <u2x0); enable="" the="" baud="" rate="" doubler="">we found directions on how to make GCC dump how much space our code was taking up!

This is a huge deal. As we program in lots of printf strings and floating point math, we need to know how much room we've got left in the IC's flash space. This small addition to your make file will allow GCC/Programmer's Notepad to show how full the IC is.

You can download an example Makefile here.

</u2x0);>

http://www.sparkfun.com/tutorial/Notepad-Tips/MemorySize-2.jpg


# Display size of file.

HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex

#New

ELFSIZE = $(SIZE) --mcu=$(MCU) --format=avr $(TARGET).elf

#Old

#ELFSIZE = $(SIZE) -A $(TARGET).elf

<u2x0); enable="" the="" baud="" rate="" doubler="">
With this trick, you'll see this in the output whenever you compile:

</u2x0);>

http://www.sparkfun.com/tutorial/Notepad-Tips/MemorySize-1.jpg


Arduino Bootloader Improved UART Accuracy


A few years ago, Atmel came out with a large development board they called the STK500. To show off what this board could do, they also released an app note called the 'STK500 Communication Protocol' that defines how to communicate serially with the board to reprogram it. It is this document that defined how the STK500 serial bootloader would work. It has been used for many years.

Along the way, the Arduino folks decided to use avrdude and the STK500 serial bootloader to program the Arduino. The Arduino bootloader is essentially the STK500 bootloader. Confused yet? All that matters is that we can program any chip, independent of the Arduino IDE using the STK500 serial protocol and bootloader.

Bootloading at a faster serial data rate is always good (at faster serial speeds, it takes less time to program a chip). The new Arduino bootloader (based originally on the STK500) now runs at 57600. There is a problem however: at faster datarates, the bit errors during serial trasmission get more noticeable - and can become a big problem.

I wanted to use an ATmega368, with the internal 8MHz oscillator, loaded with the STK500 bootloader for a project of mine. External crystals are great, but I like the skip them where I can. The original LilyPad (internal 8MHz) bootloader is exactly what I needed! Sadly, it does not work at new 57600bps speed that Arduino has gone to.

Get the latest Arduino bootloader source code here.

I tried a multitude of options trying to get the new, faster 57600 bootloader working on an ATmega168 using its internal 8MHz osc. I got it to work on one IC (date code 0921), and failed on another (date code 0921). The internal osc has a wild enough tolerance (+/-10%!!) that the bootloader is unable to communicate with avrdude. Perhaps we could user calibrate the IC...

http://www.sparkfun.com/tutorial/Notepad-Tips/AVR-OSC-S.jpg


In an attempt to get the internal 8MHz oscillator to work at 57600bps, I looked into using the baud rate doubler. The stock Arduino Bootloader (ATmegaBOOT_168.c revision 581) does not use the double speed mode of the USART. The Arduino bootloader is also using a slightly worse equation to calculate the baud rate.

http://www.sparkfun.com/tutorial/Notepad-Tips/AVR-USART-calc.jpg


The UBRR equations for normal and double speed mode.

http://www.sparkfun.com/tutorial/Notepad-Tips/AVR-8MHz-Error.jpg

<u2x0);' will="" cause="" baud="" rate="" generator="" to="" run="" twice="" as="" fast.="" by="" doing="" this,="" we="" can="" decrease="" the="" bit="" errors="" in="" some="" situations.="">
At 8MHz/57600bps (3.3V boards), this option improves the error rate a bit. From -3.5% to +2.1% (an overall reduction of error by 1.4%).

</u2x0);'>

http://www.sparkfun.com/tutorial/Notepad-Tips/AVR-16MHz-Error.jpg

<u2x0);' will="" cause="" baud="" rate="" generator="" to="" run="" twice="" as="" fast.="" by="" doing="" this,="" we="" can="" decrease="" the="" bit="" errors="" in="" some="" situations.="">
At 16MHz/57600 (5V boards), this option improves the error rate a bit as well. From 2.1% to -0.8% (an overall reduction of error by 1.3%).

I think this was not implemented when the Arduino team first started because at 19200bps, there is no error advantage (0.2% error rate at 19200bps) using the baud rate doubler (was only available on all the ATmega8/168/328 ICs). The moral of the story: if you're using the internal oscillator or a resonator and are having problems bootloading at 57600bps, you might try doubling the baud generator to lower bit errors. It works pretty well for me!

</u2x0);'>Here is my modified bootloader for Arduino that implements these changes.

Dah! I was looking at the wrong page. Arduino now hosts their source on Google Code. I was looking at the old bootloader repository. It turns out all of the UART changes mentioned above have been implemented in the latest revision. Thank you David Mellis! I'm leaving this section intact for edification of readers on UART error rates.
<u2x0);' will="" cause="" baud="" rate="" generator="" to="" run="" twice="" as="" fast.="" by="" doing="" this,="" we="" can="" decrease="" the="" bit="" errors="" in="" some="" situations.="">


</u2x0);'>

Using AVR-PG2 to program the Arduino Bootloader

<u2x0);' will="" cause="" baud="" rate="" generator="" to="" run="" twice="" as="" fast.="" by="" doing="" this,="" we="" can="" decrease="" the="" bit="" errors="" in="" some="" situations.="">
The Makefile for the stock Arduino bootloader is missing parallel port programmer option. You may want to add this programmer option to the top of the Makefile if you're playing with ATmegaBOOT_168.c:
</u2x0);'>

<u2x0);' style="font-weight: bold;" will="" cause="" baud="" rate="" generator="" to="" run="" twice="" as="" fast.="" by="" doing="" this,="" we="" can="" decrease="" the="" bit="" errors="" in="" some="" situations.="">ISPTOOL       = stk200</u2x0);'>
<u2x0);' style="font-weight: bold;" will="" cause="" baud="" rate="" generator="" to="" run="" twice="" as="" fast.="" by="" doing="" this,="" we="" can="" decrease="" the="" bit="" errors="" in="" some="" situations.="">ISPPORT       = lpt1</u2x0);'>

http://www.sparkfun.com/tutorial/Notepad-Tips/bootloader-makefile-isp.jpg
<u2x0);' will="" cause="" baud="" rate="" generator="" to="" run="" twice="" as="" fast.="" by="" doing="" this,="" we="" can="" decrease="" the="" bit="" errors="" in="" some="" situations.=""></u2x0);'>
<u2x0);' will="" cause="" baud="" rate="" generator="" to="" run="" twice="" as="" fast.="" by="" doing="" this,="" we="" can="" decrease="" the="" bit="" errors="" in="" some="" situations.="">Here is my modified Makefile for Arduino bootloader compiling with the UART accuracy improvements mentioned in the previous section.

For programming the bootloader, I really love the parallel port AVR-PG2 programmer from Olimex. It's cheap, fast, dependable, and works great with the ATmega and ATtiny series. The only downside to this programmer is that it requires a real parallel port. Many computers no longer come with this port.

 

Once you've added the 'ISPTOOL = stk200' option to the make file, compile the stock Arduino bootloader by typing the following at a command prompt:
</u2x0);'>

make clean

This will clean out any erroneous files or pre-compiled files.
<u2x0);' will="" cause="" baud="" rate="" generator="" to="" run="" twice="" as="" fast.="" by="" doing="" this,="" we="" can="" decrease="" the="" bit="" errors="" in="" some="" situations.="">
</u2x0);'>To compile, type:
make atmega328

Now to program this bootloader (16MHz) onto your ATmega328 using the awesome AVR-PG2, type:
make atmega328_isp

The PG2 will then attempt to connect to your ATmega328 (make sure it's powered on!) and load the boot loader and set the correct fuse bits. You WILL need an external 16MHz crystal or 16MHz resonator.

<u2x0);' will="" cause="" baud="" rate="" generator="" to="" run="" twice="" as="" fast.="" by="" doing="" this,="" we="" can="" decrease="" the="" bit="" errors="" in="" some="" situations.="">If you get programming errors, check your connections and try, try again. If the programming completed successfully, connect a serial connection and read on!
<u2x0); enable="" the="" baud="" rate="" doubler="">
</u2x0);>
</u2x0);'>

Serial bootloading an Arduino board

<u2x0);' will="" cause="" baud="" rate="" generator="" to="" run="" twice="" as="" fast.="" by="" doing="" this,="" we="" can="" decrease="" the="" bit="" errors="" in="" some="" situations.="">
This is a really my favorite trick of all. If you are using the STK500 (also known as the Arduino bootloader), this trick will allow you to hit a button (like F10) within Programmer's Notepad (comes with WinAVR) and get the serial bootloader to throw code down to your IC without use of the Arduino IDE (mucho rapido).

Note: I found that using Arduino 0015 didn't work so well. Arduino 0017 works like a charm.
</u2x0);'>
<u2x0);' will="" cause="" baud="" rate="" generator="" to="" run="" twice="" as="" fast.="" by="" doing="" this,="" we="" can="" decrease="" the="" bit="" errors="" in="" some="" situations.="">1) First, grab this blink.c program and Makefile from here.
</u2x0);'>
<u2x0);' will="" cause="" baud="" rate="" generator="" to="" run="" twice="" as="" fast.="" by="" doing="" this,="" we="" can="" decrease="" the="" bit="" errors="" in="" some="" situations.="">2) Next, grab an Arduino Pro 5V/16MHz. (You can use any AVR, ATmega168, 8MHz, 10MHz, anything, but you'll need to compile and load a bootloader correctly.)</u2x0);'> Hook up an FTDI Basic board and use Windows Device Manager to determine which COM port the board is living on. It was COM7 for me.

3) Now edit the Makefile with the COM port # you just found (and any different arduino path that you may be using):

http://www.sparkfun.com/tutorial/Notepad-Tips/Serial-Bootload8.jpg

4) Plug the FTDI Basic onto the Pro board. The power LED should come on.

5) From within Programmer's Notepad, create a new Serial Program tool (read the previous section on how to create hot keys if you are lost):

http://www.sparkfun.com/tutorial/Notepad-Tips/Serial-Bootload9.jpg


6) Click Ok a couple times. Now, from the main Programmer's Notepad window, hit F10:

http://www.sparkfun.com/tutorial/Notepad-Tips/Serial-Bootload10.jpg

Yes! Success! And so much faster than Java. This is a very fast programming/development cycle rather than using the Arduino IDE. We <3 Arduino, but when you're a stick-in-the-mud C programmer like me, it's nice to be able to return to the friendly Programmer's Notepad environment.

<u2x0);' will="" cause="" baud="" rate="" generator="" to="" run="" twice="" as="" fast.="" by="" doing="" this,="" we="" can="" decrease="" the="" bit="" errors="" in="" some="" situations.=""><u2x0); enable="" the="" baud="" rate="" doubler=""></u2x0);><u2x0); enable="" the="" baud="" rate="" doubler=""><adif)|(1><adsc); clear="" any="" previous="" by="" writing="" a="" 1="" into="" adif="" and="" start="" conversion=""><adif)) 0);="" wait="" for="" adc="" to="" complete=""><adif)|(1><adsc); clear="" any="" previous="" by="" writing="" a="" 1="" into="" adif="" and="" start="" conversion=""><adif)) 0);="" wait="" for="" adc="" to="" complete="">
Enjoy!
-Nathan
</adif))></adsc);></adif)|(1></adif))></adsc);></adif)|(1></u2x0);></u2x0);'>

Comments 10 comments

  • Member #168665 / about 13 years ago / 1

    Just got my Arduino Uno in, was not interested in programming with Arduino IDE since I'm already using winavr. Your serial bootloading helped out. Although with the UNO the baud needs to be 115200, works like a charm. Also, wanted some hotkeys for make and program, thanks a lot for posting this tutorial.

  • I am an Ubuntu fan-boy. So I am stuck is there any way to do this in linux?

    • Marche / about 13 years ago / 1

      What would you like to do specifically?
      Under emacs or geany you can set a custom build command, which I've set to run a script that tries to find a makefile in the directory above the current one, compiles using that makefile, runs objcopy on the resulting binary to get a hex dump, and then flashes my arduino using avrdude.
      Most of this was modeled on what the arduino ide does. You can get it to show exactly what commands are being run during the build process by holding shift while you press the upload button. (Make sure you get GCC's options right, otherwise your code will be HUGE!)

  • mellis / about 15 years ago / 1

    The Arduino source code is now hosted on Google Code. You can find the bootloader here: http://code.google.com/p/arduino/source/browse/#svn/trunk/hardware/bootloaders

    • O hai David! Thanks for the updated links. Looks like the latest rev of the bootloader has the UART changes (double speed) already implemented - thanks! I've updated the tutorial with links that now point to google code.

  • motopic / about 15 years ago / 1

    um, a link?
    Programmers Notepad2: http://www.pnotepad.org/
    Get the portable version and install it on your usb stick.

  • RABeng / about 15 years ago / 1

    Great write up Nate!
    Why is the Arduino 0017 needed? If you have WinAVR installed can you just navigate to the avrdude and avrdude.conf under that directory in the makefile?
    Thanks Again!

    • Let me try to remember. I believe it had to do with older avrdude.conf files packaged with Arduino not knowing what to do with 'atmega328'. The newer Arduino releases obviously support this newer IC.

  • CalcProgrammer1 / about 15 years ago / 1

    Awesome! I just purchased an Arduino as well as an extra ATMega328 from here last week. I didn't get the bootloaded 328 because I figured I could install it myself and wanted to use the bare chip for regular AVR C programming. I would rather be able to program the chip using a bootloader though. Just to make sure, the modified bootloader is configured for the internal 8MHz resonator right? I want to run my ATMega328 with a bootloader for easy programming but I only have the internal 8MHz resonator and a 20MHz crystal (and my Arduino but I don't want to take the chip off of it).

    • A very good plan! Make sure you have a good programmer and you should have very little problems. The bootloader described above is configured for an ATmega328 with external 16MHz resonator/crystal. To compile the bootloader to work at internal 8MHz, type 'make lilypad' to compile the lilypad bootloader (internal 8MHz) and 'make lilypad_isp' to program the bootloader. I would recommend changing '-DMAX_TIME_COUNT=F_CPU>>1' in the Makefile lilypad cflags to '-DMAX_TIME_COUNT=F_CPU>>4'. This will make the time from power-up/reset to program execution much shorter/faster.
      To compile the bootloader to run at 20MHz, you will need to change the line: 'atmega328: AVR_FREQ = 16000000L' to 'atmega328: AVR_FREQ = 20000000L' inside the Makefile and then compile and program as described in the tutorial.