Introduction to Bootloader for AVR

What is a boot loader ? A boot loader is basically a program that you put in a special part of a microcontrollers memory that allows you to program the microcontroller without external hardware.

For this How To I’ll be using the ATmega32 as the microcontroller, but by the end of this article you should know enough to easily adapt it to other AVRs.

Getting Started:

The question you are probably asking now is “where do I get a boot loader?” The answer is you can either program your own or use someone else’s. For this example we’ll be using the excellent “Fast Tiny & Mega Uart Bootloader” from Danni at AVRFreaks. Depending on the microcontroller you are using you may need to change the TX and RX pins and ports in BOOTLOAD.asm to match those of your microcontroller. BOOTLOAD.asm is located in the BOOTLOAD folder. After you have made any necessary changes, you need to assemble it using the assembler that comes with AVR Studio. This will create a file called BOOTLOAD.hex, you will be using this file later. You also need to decide what communication protocol you want to use with your microcontroller (usb, rs232, etc.) so that you can get the appropriate IC to interface between the UART of the microcontroller and your computer. I used a ft232RL USB to UART bridge. The schematic for hooking up the ft232RL is right in the datasheet:

You don’t need the ferrite bead that is in the schematic unless you are worried about noise. In this configuration the FT232RL will be powered through USB. However, your microcontroller should have a separate power supply so that it can be turned on separately.

Programming the Boot loader in the Right Place:

To use your boot loader you have to split up the microcontroller’s flash memory into two parts: the boot loader section and the application section. The boot loader section is obviously where the boot loader is stored. The application section is where your main code is stored. By “main code” I mean whatever you have programmed your microcontroller to do Ex. Blink an L.E.D.. You have to have a separate section for the boot loader, otherwise it will get overwritten every time you upload a new “main code”.

AVRs have what are called “fuses”. Unlike mechanical fuses, these do not protect from over current, rather they are like configuration files that tell the microcontroller what clock frequency it’s supposed to run at, what voltage to shutdown at, etc.. Turns out we can use a special kind of fuse called a “Lock Bit” to lock part of the AVRs memory so that the boot loader cannot be overwritten. Besides lock bits, fuses are separated into two different categories: low fuse byte and high fuse byte, we will learn more about these later.

Understanding the Datasheet:

To find out what fuses to program, we have to look at the datasheet of our microcontroller and find information about the different fuses and lock bits. First, let’s look at all the different lock bits of an ATmega32:

As you can see, bits 7, 6, 1, and 0 should always equal 1. However, bits 5, 4, 3, and 2 are changeable. To figure out what these lock bits do, you have to find a different table in your microcontroller’s datasheet:

These tables tell you about the different bits you have to program/unprogram to get different modes. The default mode for the ATmega32 is to leave them all unprogrammed. Now lets move on to high fuse bits and low fuse bits. Here are all the fuses for the high byte:

The only fuses that are relative to boot loaders in this byte are the BOOTSZ1, BOOTSZ0 and BOOTRST fuses. Let’s take a look at table 99 and see if we can decode the meanings of these fuses:

This is pretty straight forward, all that the BOOTSZ1 and BOOTSZ0 fuses do is specify how much of the memory should be “set aside” for the boot loader. Usually if you are using someone else’s boot loader, they will specify how many words of space it needs. For the Fast Tiny & Mega Uart Bootloader we only need 256 words of space. The BOOTRST fuse is not explained very well, but you need to have this fuse programmed. It is the fuse that tells the microcontroller to boot up at the beginning of your boot loader code. Now that we have the high fuse byte figured out, let’s move on to the low fuse byte. Here is the table in the ATmega32 datasheet for that:

Obviously, these fuses have to do with selecting the correct clock frequency, start-up time, and brown-out trigger. You can pretty much leave these alone, unless you are using an external crystal, or want to select a different internal oscillator frequency.

Putting All This New Knowledge to Use:

Now that you now all about the different fuses of the ATmega32, let’s go through this information and formulate a few lines of binary that will define the different fuse settings. Before we get to that I’ll outline the process of getting the boot loader into the ATmega32:

Step1: Erase chip
Step2: Set low fuse byte
Step3: Set high fuse byte
Step4: Unlock boot loader section
Step5: Program boot loader into micro-controller
Step6: Lock the boot loader section so that it cannot be erased

Now that we know this, we can start figuring out which fuses should be programmed, and which shouldn’t. Let’s start out with the low fuse byte, this is pretty simple because, as I said before, unless you are using a different clock frequency you can leave all of these fuses as default. For purposes of thoroughness, here are those values:

CKDIV8     =     0 (default)
CKOUT      =     1 (default)
SUT1      =     1 (default)
SUT0      =     0 (default)
CKSEL3     =     0 (default)
CKSEL2     =     0 (default)
CKSEL1     =     1 (default)
CKSEL0     =     0 (default)

Here are the high fuse bits:

RSTDISBL= 1 (default)
DWN = 1 (default)
SPIEN = 0 (default)
WDTON = 1 (default)
EESAVE = 1 (default)
BOOTSZ1 = 1 (changed)
BOOTSZ0 = 1 (changed)
BOOTRST = 0 (changed)

Here we see that everything is left default except for BOOTSZ1, BOOTSZ0, and BOOTRST. Having BOOTSZ1 and BOOTSZ0, unprogrammed, in accordance to table 99 selects a boot size of 256 words. Programming BOOTRST tells the microcontroller to start from the beginning of the boot loader code. Finally, let’s see how we should handle the lock bits. To unlock the boot loader section we need to program these lock bits, as per tables 95 and 96:

Bit7 = 1 (default)
Bit6 = 1 (default)
BLB12 = 1 (default)
BLB11 = 1 (default)
BLB02 = 1 (default)
BLB01 = 1 (default)
LB2 = 1 (default)
LB1 = 1 (default)

After that we need to program the boot loader into the boot loader section, more about this later. To lock the boot loader section we need to program these lock bits, again according to tables 95 and 96:

Bit7 = 1 (default)
Bit6 = 1 (default)
BLB12 = 1 (default)
BLB11 = 0 (changed)
BLB02 = 1 (default)
BLB01 = 1 (default)
LB2 = 1 (default)
LB1 = 1 (default)

This selects Application Section mode 1 which says “No restrictions for SPM or LPM accessing the Application section”. It also selects Boot Loader Section mode 2, which says “SPM in not allowed to write to the Boot Loader section”. This means that you will be able to program the application section (the part where your main code is). But you will not be able to program the boot loader section.

(Finally!) Programming the Boot Loader using AVRDUDE:

For this step you need a hardware programmer to program the bootloader into the chip, I used this one. To use the binary code we just figured out, we need to convert it to hexadecimal. These are the hexadecimal values for the previous binary:

Low Fuse Byte (01100010) = 62
High Fuse Byte (11011110) = DE
Lock bits for unlocking boot loader section (11111111) = FF
Lock bits for locking boot loader section (11101111) = EF

And finally, here are the lines for avrdude that you can use in Terminal or Command Prompt to program your microcontroller. To use this you need to be in the directory of the BOOTLOAD.hex file you created earlier.

avrdude -c ponyser -p m32 -P /dev/ttyS0 –e
avrdude -c ponyser -p m32 -P /dev/ttyS0 -U lfuse:w:0xE1:m -U hfuse:w:0x9E:m
avrdude -c ponyser -p m32 -P /dev/ttyS0 -U lock:w:0xFF:m
avrdude -c ponyser -p m32 -P /dev/ttyS0 -D -U flash:w:BOOTLOAD.hex:i
avrdude -c ponyser -p m32 -P /dev/ttyS0 -U lock:w:0xEF:m

The –P and -c options needs to be changed depending on what hardware programmer you are using, as well as –p depending on what microcontroller you are using.

Now that you know the hard way to figure out fuse values, I’ll tell you that you can also use this AVR fuse calculator, which is much easier.

How to Use the Boot Loader:

Now That you have the boot loader in the microcontroller, you can use it! First you need to change directory (cd) in command prompt or terminal to the FBOOT folder of the bootloader folders you downloaded earlier. The .hex file of your main code should also be in the FBOOT folder. Now plug in your ft232rl chip that you should have hooked up to your microcontroller. Then you need to type this in command prompt:

fboot.exe -b1200 -c1 -pfile.hex -vfile.hex

file.hex should be changed to the name of the hex file you want to program into your microcontroller. You may want to use a higher baud rate (the -b option) if you are using an external crystal of a higher frequency. Also, you may need to change c1 to something different like c2 or c3, depending on what com port you have your ft232rl plugged in to. After you have done this you should see a spinning ”/” symbol. Now turn on your microcontroller and it should start programming!

The end! I hope you enjoyed this How To.

Author: admin on March 24, 2014
Category: AVR

Leave a Reply

Last articles