where : ibrtses embedded
AVR bootloader
The time came to write a bootloader. When a bootloader is not communicating with the PC software the device usually does, then an additional software is required for the loading process. This additional software hast to be understood, delivered, maintained. Experience tells me that a bootloader has to fit into the application. It has to use the same protocol, the same baudrate (or provide for the change) and they have to have the same timing as the application.
A first glance at the capabilities of the AVR.
the capabilities of the AVR
The AVR can program, the bootsecor as well as the application memory. The difference is that during programming of the bootsector, the code is halted. We'll here not further refer to the bootsector programming, but stay with the application programming. The boundary between these read-while-write and non-read-while-write is presettable. The bootsector can be either 512, 1024or 2048 bytes. Part or all of this bootcode can be locked. The main instructions are LPM load programm memory, SPM store program memory and content of the the SPMCR Store Program Memory Control Register. This control register allows to clear as well as write a page.
PageSize
The page sizes of the various cpu's are
CPU |
Flashsize Words |
pagesize bytes |
Flash pages |
EEPROMSize bytes |
pagesize bytes |
EEPROM pages |
Mega16 |
8k |
64 |
128 |
512 |
1 |
512 |
Mega32 |
16k |
64 |
256 |
1024 |
4 |
256 |
Mega64 |
32k |
128 |
512 |
2048 |
1 |
2048 |
Mega128 |
64k |
128 |
512 |
4096 |
8 |
512 |
The Mega32 and the Mega324 are identical what the bootloader concerns.
The Mega16, the Mega164 and the Mega169 are identical what the bootloader concerns.
We won't refer to them any further.
Bootblock Size
The sizes of the boot blocks for various cpu's are
CPU |
Boot SZ 1,0 |
Bootsize Words |
pages |
Application |
Bootloader |
Boot Adress |
Mega16 |
1 1 |
128 |
2 |
0x0000..0x1F7F |
0x1F80..0x1FFF |
0x1F80 |
* |
1 0 |
256 |
4 |
0x0000..0x1EFF |
0x1F00..0x1FFF |
0x1F00 |
* |
0 1 |
512 |
8 |
0x0000..0x1DFF |
0x1E00..0x1FFF |
0x1E00 |
* |
0 0 |
1024 |
16 |
0x0000..0x1BFF |
0x1C00..0x1FFF |
0x1C00 |
Mega32 |
1 1 |
256 |
4 |
0x0000..0x3EFF |
0x3F00..0x3FFF |
0x3F00 |
* |
1 0 |
512 |
8 |
0x0000..0x3DFF |
0x3E00..0x3FFF |
0x3E00 |
* |
0 1 |
1024 |
16 |
0x0000..0x3BFF |
0x3C00..0x3FFF |
0x3C00 |
* |
0 0 |
2048 |
32 |
0x0000..0x37FF |
0x3800..0x3FFF |
0x3800 |
Mega64 |
1 1 |
512 |
4 |
0x0000..0x7DFF |
0x7E00..0x7FFF |
0x7E00 |
* |
1 0 |
1024 |
8 |
0x0000..0x7BFF |
0x7C00..0x7FFF |
0x7C00 |
* |
0 1 |
2048 |
16 |
0x0000..0x77FF |
0x7800..0x7FFF |
0x7800 |
* |
0 0 |
4096 |
32 |
0x0000..0x6FFF |
0x7000..0x7FFF |
0x7000 |
Mega128 |
1 1 |
512 |
4 |
0x0000..0xFDFF |
0xFE00..0xFFFF |
0xFE00 |
* |
1 0 |
1024 |
8 |
0x0000..0xFBFF |
0xFC00..0xFFFF |
0xFC00 |
* |
0 1 |
2048 |
16 |
0x0000..0xF7FF |
0xF800..0xFFFF |
0xF800 |
* |
0 0 |
4096 |
32 |
0x0000..0xEFFF |
0xF000..0xFFFF |
0xF000 |
Keep in mind that an average ASM instruction takes one word (2 bytes), so the number of words in the boot block is roughly the number of ASM instruction. Subtract the interrupt table if necessary.
The program flow
At powerup the Resetvector jumps either to
- the Application start at Adress 0x0000, if the BootRST fuse = 1 (unprogrammed)
- the Bootsector at the top of the adress range, if the BootRST fuse = 0 (programmed)
This fuse cannot be changed by software.
A rather interesting feature is that the interrupts can be executed from the application section as well as from the boot block section. The interrupts can be changed on the fly in both sections from code, when the fuses permit. Have a look at the GICRorMCUCR General interrupt Control Register. For the permitting fuses have a look at the Boot Lock Bits.
Beside that the to be programmed section is not readable while programming, the code can jump back and forth between bootcode and aplication code.
The programming details
The programming of the application memory happens page by page. Each page has to be erased before programming. A page is erased by setting the PGERS : PageErase, Bit 1 of SPMCR after setting the ZPointer to the page.
Erasing a page appears to take 9ms according to the Mega32 datasheet.
Writing a page takes 4.5ms according to the Mega32 datasheet (2503I-AVR-4/06)
Bootloader Protocols
There are infinitely many thinkable protocols for a bootloader. Some are more compact than others. After several week trying to get something together with a compiler we found the bootloader to be an ASM thing. It is rather easy to gain a factor of two in code size, which is, with the scarce resource, a must. In one application we did choose a http protocol for the bootloader, such that a device can be programmed by a browser. This project will be outlined later.
what is to be programmed
Depending on the application, the following features are thinkable beside the application flash.
- an external flash
- the internal eeprom
- an external eeprom
- external hardware, such as a flash based FPGA
how does the programming protocol work
Some apparent details. Apparently the to be programmed space is much larger than any available buffer, and thus the receiving routine has to do the programming while the reception is running. Erasing a page and writing a page takes longer than receiving a byte at 9600. This requires some buffer mechanism. We decided the increased overhead of having interrupts not being worth the gain, but that may depend on the application.
to be continued ...
Questions ?
Suggestions?
Feedback ?
sponsored links
home
the embedded pages
the AVR pages
last updated 27.Sept.07, or perhaps later
Copyright (99,2007) Ing.Büro R.Tschaggelar