Forum Menu




 


Log in Problems?
New User? Sign Up!
AVR Freaks Forum Index

Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Author Message
schickb
PostPosted: May 19, 2009 - 01:47 AM
Hangaround


Joined: May 07, 2007
Posts: 291
Location: Seattle

Planning to create a custom bootloader? This document answers many of the questions you may have. Most of the concepts covered within are not discussed thoroughly in datasheets, and various tips for designing a robust bootloader are provided.

Table of Contents

1. How do I get started?
2. What are the NRWW and RWW regions?
3. How does the bootloader update the application?
4. Can a bootloader update fuses?
5. What is BOOTLOADER_SECTION in <avr/boot.h> for?
6. How do I program the bootloader to the MCU?
7. How do I program both the application and the bootloader?
8. Can a bootloader use interrupts?
9. Should the bootloader or the application run first?
10. How does the bootloader know when to start the application?
11. How does the bootloader start the application?
12. How can the bootloader be sure the application is intact?
13. Can the bootloader use code built into the application?
14. Can the application use code built into the bootloader?
15. Why can't global variables be accessed from shared functions?
16. Can the application use an ISR built into the bootloader?
17. How can a shared ISR access global data?
18. Can I save space in a bootloader with few or no ISRs?

Thanks to Cliff Lawson for reviewing and contributing to this FAQ.

Edit May 19, 2009: Fixed a few typos in the FAQ (old download count 30)

_________________
-Brad


Last edited by schickb on May 19, 2009 - 06:58 PM; edited 1 time in total
 
 View user's profile Send private message  
Reply with quote Back to top
Trepan
PostPosted: May 19, 2009 - 01:24 PM
Rookie


Joined: Mar 11, 2008
Posts: 24
Location: Moncton, NB

This is great
 
 View user's profile Send private message  
Reply with quote Back to top
AndersAnd
PostPosted: May 19, 2009 - 01:55 PM
Posting Freak


Joined: Apr 23, 2003
Posts: 1126
Location: Denmark

Nice.
I think you should add something about what AVR models support bootloaders. Are there any general rules about this, like only ATmegas or all AVRs - only devices above xx kB flash and/or xx number of pins - or other general rules to easily tell what devices support bootloaders without going through all datasheets whenever you want to find one that supports bootloaders.
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: May 19, 2009 - 02:54 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62230
Location: (using avr-gcc in) Finchingfield, Essex, England

A quick scan through the datasheets I happen to have on my drive here suggests that the only chip I can find that does not have a "self programming the flash" section is the tiny12. Even the 1K tiny13 has that section. Though I guess the true indicator of "real" bootloader support is the presence of a BOOTRST fuse.

Not sure if anyone has ever waded through the entire datasheet collection to see which DO and which DON'T have BOOTRST though?

EDIT: Ah ha! Just thought of a way to identify them:
Code:
C:\WinAVR-20090313\avr\include\avr>grep FUSE_BOOTRST *.h
io90pwm1.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
io90pwm216.h:#define FUSE_BOOTRST  (unsigned char)~_BV(0)  /* Select Reset Vector */
io90pwm2b.h:#define FUSE_BOOTRST (unsigned char)~_BV(0)  /* Select Reset Vector */
io90pwm316.h:#define FUSE_BOOTRST  (unsigned char)~_BV(0)  /* Select Reset Vector */
io90pwm3b.h:#define FUSE_BOOTRST (unsigned char)~_BV(0)  /* Select Reset Vector */
io90pwm81.h:#define FUSE_BOOTRST  (unsigned char)~_BV(0)  /* Select Reset Vector  */
io90pwmx.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
io90scr100.h:#define FUSE_BOOTRST  (unsigned char)~_BV(0)  /* Select Reset Vector */
ioa6289.h:#define FUSE_BOOTRST ~_BV(0)  /* Select reset vector */
iocan128.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iocan32.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iocan64.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom128.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom1280.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom1281.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom1284p.h:#define FUSE_BOOTRST (unsigned char)~_BV(0)  /* Select Reset Vector */
iom128rfa1.h:#define FUSE_BOOTRST    ~_BV(0) /* Select Reset Vector */
iom16.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom161.h:#define FUSE_BOOTRST     (unsigned char)~_BV(6)
iom162.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom163.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom164.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom165.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom165p.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom168.h:#define FUSE_BOOTRST (unsigned char)~_BV(0)
iom168p.h:#define FUSE_BOOTRST (unsigned char)~_BV(0)
iom169.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom169p.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom16m1.h:#define FUSE_BOOTRST  (unsigned char)~_BV(0)  /* Select Reset Vector */
iom16u4.h:#define FUSE_BOOTRST  (unsigned char)~_BV(0)  /* Select Reset Vector */
iom2560.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom2561.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom32.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom323.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom324.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom325.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom3250.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom328p.h:#define FUSE_BOOTRST (unsigned char)~_BV(0)
iom329.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom3290.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom32c1.h:#define FUSE_BOOTRST  (unsigned char)~_BV(0)  /* Select Reset Vector */
iom32hvb.h:#define FUSE_BOOTRST   (unsigned char)~_BV(0)  /* Select Reset Vector */
iom32m1.h:#define FUSE_BOOTRST  (unsigned char)~_BV(0)  /* Select Reset Vector */
iom32u4.h:#define FUSE_BOOTRST (unsigned char)~_BV(0)  /* Select Reset Vector */

iom32u6.h:#define FUSE_BOOTRST  (unsigned char)~_BV(0)  /* Select Reset Vector */
iom406.h:#define FUSE_BOOTRST (unsigned char)~_BV(3)
iom64.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom640.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom644.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom645.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom6450.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom649.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom6490.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom64c1.h:#define FUSE_BOOTRST  (unsigned char)~_BV(0)  /* Select Reset Vector */
iom64m1.h:#define FUSE_BOOTRST  (unsigned char)~_BV(0)  /* Select Reset Vector */
iom8.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom8515.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom8535.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iom88.h:#define FUSE_BOOTRST (unsigned char)~_BV(0)
iom88p.h:#define FUSE_BOOTRST (unsigned char)~_BV(0)
iousb1286.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iousb1287.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iousb162.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iousb646.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iousb647.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iousb82.h:#define FUSE_BOOTRST     (unsigned char)~_BV(0)
iox128a1.h:#define FUSE_BOOTRST  ~_BV(6)  /* Boot Loader Section Reset Vector */
iox128a3.h:#define FUSE_BOOTRST  ~_BV(6)  /* Boot Loader Section Reset Vector */
iox16a4.h:#define FUSE_BOOTRST  ~_BV(6)  /* Boot Loader Section Reset Vector */
iox16d4.h:#define FUSE_BOOTRST  ~_BV(6)  /* Boot Loader Section Reset Vector */
iox256a3.h:#define FUSE_BOOTRST  ~_BV(6)  /* Boot Loader Section Reset Vector */
iox256a3b.h:#define FUSE_BOOTRST  ~_BV(6)  /* Boot Loader Section Reset Vector */
iox32a4.h:#define FUSE_BOOTRST  ~_BV(6)  /* Boot Loader Section Reset Vector */
iox32d4.h:#define FUSE_BOOTRST  ~_BV(6)  /* Boot Loader Section Reset Vector */
iox64a1.h:#define FUSE_BOOTRST  ~_BV(6)  /* Boot Loader Section Reset Vector */
iox64a3.h:#define FUSE_BOOTRST  ~_BV(6)  /* Boot Loader Section Reset Vector */

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
AndersAnd
PostPosted: May 19, 2009 - 04:50 PM
Posting Freak


Joined: Apr 23, 2003
Posts: 1126
Location: Denmark

clawson wrote:
A quick scan through the datasheets I happen to have on my drive here suggests that the only chip I can find that does not have a "self programming the flash" section is the tiny12. Even the 1K tiny13 has that section. Though I guess the true indicator of "real" bootloader support is the presence of a BOOTRST fuse.

Thank you for the list.

I don't think I have ever seen a bootloader that supports AVRs without "Read-While-Write Self-Programming" (AVRs with BOOTRST fuse).
Is is actually possible to make a bootloader for devices without BOOTRST? And if so, why don't we see any bootloaders supporting these devices? OR does anyone have a link to a bootloader supporting an AVR without BOOTRST fuse?

For example ATmeaga48PA and 88PA share the same datasheet: http://www.atmel.com/dyn/resources/prod ... oc8161.pdf
But only the 88PA has the Read-While-Write Self-Programming (BOOTRST fuse). (See section 26. Boot Loader Support – Read-While-Write Self-Programming, ATmega88PA)
I have seen many bootloaders supporting 88PA, but haven't seen any also supporting 48PA without the BOOTRST fuse.

I think ATmega88PA is the smallest and cheapest AVR that supports bootloaders. There's no ATtiny's, regular "old" AT90Sxxx (or ATmeaga48PA as I mentioned) in your list of devices with BOOTRST fuse. And I have never seen a bootlaoder for these devices either.
Looks like all ATmegas with >= 8kB flash (all of them except ATmega48(PA) has the BOOTRST fuse.


Last edited by AndersAnd on May 19, 2009 - 05:04 PM; edited 1 time in total
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: May 19, 2009 - 05:03 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62230
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

Is is possible to make a bootloader for devices without BOOTRST? And if so, why don't we see any bootloaders supporting these devices?

That's really almost the same question about reprogramming a bootloader with a bootloader. The problem is doing SPM in the same section as is being replaced. In theory it can be done by having two lots of SPM code. (often refrerred to as a Primary Boot Loader and a Secondary Boot Loader PBL/SBL). First the PBL would receive and then program the SBL in another part of the same section,then control would pass to the SBL which would receive and program a replacement for the PBL. But this kind of opens the system up to "rug from under your own feet" problems. Clearly the intention of Atmel in providing and allowing SPM to run in the single section AVRs was that the flash *could* be self programmed but I imagine the intention was simply so a datatable or something could be replaced - not that the code could pull the rug from under its own feet.

So whether anyone has ever achieved a complete self-reprogram in either the entire flash of a single section AVR or within the NRWW section of a dual section AVR is one of the great unsolved mysteries.

Some folks suggest that things like hard coding boot routine addresses in the app is a "dangerous thing" in case the bootloader itself is ever replaced but until someone actually manages to replace an AVR's own bootloader I think it's a moot point.

Cliff

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
schickb
PostPosted: May 19, 2009 - 06:42 PM
Hangaround


Joined: May 07, 2007
Posts: 291
Location: Seattle

clawson wrote:
Some folks suggest that things like hard coding boot routine addresses in the app is a "dangerous thing" in case the bootloader itself is ever replaced but until someone actually manages to replace an AVR's own bootloader I think it's a moot point.


I think there are two risks with hard-coding addresses like this.

1. During design and development, there may be a bunch of prototype devices floating around and more than one person working on a project. It is just too easy to update the bootloader with an ISP and forget to update hard-coded addresses and rebuilt the application. Or even remember to update addresses, but miss one function by mistake. Its both a hassle to work like this and a potential time waster if someone screws up.

2. Even worse is if after releasing devices into the wild you find a bug in the bootloader that should be fixed. If you fix this bug for new devices without recalling or discarding all existing devices, you now have a potentially tricky application update problem. You need two versions... one for the old BL and one for the new BL.

I totally agree that a bootloader should be rock-solid and hopefully never change once a device has shipped. But if I've learned anything after decades of software work it is that anything can be screwed up Wink

I am thinking of a senario like this: A consumer device has shipped 5,000 units already when you start getting reports that app firmware updates don't work on 3+ year old iMacs. You find that there is a small USB tweak to the bootloader that could fix the issue. Given that most device owners are unaffected by the problem, you update the BL for new devices and simply replace old ones when people report a problem. But if you've hard-coded addresses you now have up to 5,000 devices that need a different version of the app firmware.

Sure, your bootloader and application could have version numbers to report an error if they are incompatible, but a jump table (question #14) is an easy and small solution that will give your customers a better experience. I personally think it is hard to justify taking even a small risk on hard-coded addresses when an easy improvement is available.

_________________
-Brad


Last edited by schickb on May 19, 2009 - 07:06 PM; edited 2 times in total
 
 View user's profile Send private message  
Reply with quote Back to top
schickb
PostPosted: May 19, 2009 - 07:02 PM
Hangaround


Joined: May 07, 2007
Posts: 291
Location: Seattle

AndersAnd wrote:
I think you should add something about what AVR models support bootloaders. Are there any general rules about this, like only ATmegas or all AVRs - only devices above xx kB flash and/or xx number of pins...


Looks like Cliff uploaded a good snapshot of the current support. I don't really want to add this to the FAQ since it will constantly be changing. Also I think it is safe to assume that except for a few speciality AVRs, most new chips are going to support bootloaders with RWW/NRWW sections.

_________________
-Brad
 
 View user's profile Send private message  
Reply with quote Back to top
AndersAnd
PostPosted: May 19, 2009 - 08:17 PM
Posting Freak


Joined: Apr 23, 2003
Posts: 1126
Location: Denmark

schickb wrote:
Also I think it is safe to assume that except for a few speciality AVRs, most new chips are going to support bootloaders with RWW/NRWW sections.

Sorry, but I think it's safe to say that this is not true at all.
Best eaxmple is the ATmega48PA which is one of the newset of all the AVRs, and even though it's almost identical bigger brother ATmega88PA has a bootloader section, this is not the case with 48PA.
As I mentioned ATmega48PA + all of the ATtinys doesn't have a bootloader section.
Another good example is ATtiny88 which is one of the newset ATtinys (kind of a discount version of ATmega88PA) and this does not have a bootloader section even though it has 8kB of Flash like ATmega88PA with bootlaoder does: http://www.atmel.com/dyn/resources/prod ... oc8008.pdf
Maybe it's safe to say all new ATmegas with flash >= 8kB has a bootloader section, but that none of the AT90Sxxxx or ATtinys (brand new or old) has a bootlaoder section, even the largest one with 8kB flash.

My point with thsi whole discussion was that one can get the impression that all AVRs has a seperate boot section, which is not true.
I can understand why you don't want a complete list of AVRs with seperate boot section. But I think it's a good idea to mention that only the largest AVRs has a seperate boot section.
It could be more specific and say currently none of the AT90Sxxxx or ATtiny has boot sections and only ATmegas with >= 8kBflash.
Just make the reader aware that the smallest AVRs doesn't have a boot section.

It makes sense why they don't add bootloader sections to the smallest flash size AVRs, as a bootlaoder in itself takes up quite a lot of flash.
But ATtiny88 could have had a bootloader when ATmega88PA does. But they have probably left it out in all ATtinys even the biggest ones to reduce cost.
 
 View user's profile Send private message  
Reply with quote Back to top
schickb
PostPosted: May 19, 2009 - 08:53 PM
Hangaround


Joined: May 07, 2007
Posts: 291
Location: Seattle

AndersAnd wrote:
schickb wrote:
Also I think it is safe to assume that except for a few speciality AVRs, most new chips are going to support bootloaders with RWW/NRWW sections.

Sorry, but I think it's safe to say that this is not true at all.
Best eaxmple is the ATmega48PA which is one of the newset of all the AVRs, and even though it's almost identical bigger brother ATmega88PA has a bootloader section, this is not the case with 48PA.
As I mentioned ATmega48PA + all of the ATtinys doesn't have a bootloader section.


Well by "speciality" (or is that specialty) I mostly meant low flash devices. Beyond the Tinys, I only count 9 current AVRs with < 8K of flash and 7 of those are automotive.

But your point it taken, you can't assume all devices have a proper bootloader section without checking.

I'd just rather have Atmel maintain such a list in their parametric product table than do it myself Wink

_________________
-Brad
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: May 19, 2009 - 09:00 PM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62230
Location: (using avr-gcc in) Finchingfield, Essex, England

I posted the list above - I think you can take the .h files in GCC to be as definitive as either the XML partdescription files or the datasheets

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
AndersAnd
PostPosted: May 19, 2009 - 09:10 PM
Posting Freak


Joined: Apr 23, 2003
Posts: 1126
Location: Denmark

schickb wrote:
Well by "speciality" (or is that specialty) I mostly meant low flash devices. Beyond the Tinys, I only count 9 current AVRs with < 8K of flash and 7 of those are automotive.

Atmel's definition of speciality AVRs is all the ones not listed under the generic ATtiny and ATmega sections (and maybe XMEGA) here: http://www.atmel.com/dyn/products/devic ... ily_id=607

So speciality AVRs would be Automotive AVR, Lighting AVR, AVR Z-Link, Battery Management AVR, CAN AVR, USB AVR and LCD AVR.
 
 View user's profile Send private message  
Reply with quote Back to top
schickb
PostPosted: May 19, 2009 - 09:46 PM
Hangaround


Joined: May 07, 2007
Posts: 291
Location: Seattle

clawson wrote:
I posted the list above - I think you can take the .h files in GCC to be as definitive as either the XML partdescription files or the datasheets


I just don't want to update the FAQ every time Atmel adds a new part. Maybe the best solution would be to add another entry to the document that tells people how to grep the avr-libc headers to figure it out for themselves.

And at the same time maybe someone should email Atmel and ask them to add that to their parametric tables Wink

_________________
-Brad
 
 View user's profile Send private message  
Reply with quote Back to top
clawson
PostPosted: May 20, 2009 - 09:46 AM
10k+ Postman


Joined: Jul 18, 2005
Posts: 62230
Location: (using avr-gcc in) Finchingfield, Essex, England

Quote:

Maybe the best solution would be to add another entry to the document that tells people how to grep the avr-libc headers to figure it out for themselves.

Or I'll just do that grep and post it here each time a new WinAVR is released. Wink

_________________
 
 View user's profile Send private message  
Reply with quote Back to top
thefool
PostPosted: May 23, 2009 - 10:01 AM
Wannabe


Joined: Nov 18, 2008
Posts: 79


schickb wrote:
Planning to create a custom bootloader? This document answers many of the questions you may have. Most of the concepts covered within are not discussed thoroughly in datasheets, and various tips for designing a robust bootloader are provided.


Hi, Thanks for the document, sounds like just what I need. But I thought I'd let you know it's entirely unreadable with the built-in Mac OS X "Preview" Program.
(See the Screenshot).
What PDF writer did you use?
 
 View user's profile Send private message  
Reply with quote Back to top
schickb
PostPosted: May 23, 2009 - 04:25 PM
Hangaround


Joined: May 07, 2007
Posts: 291
Location: Seattle

thefool wrote:
Hi, Thanks for the document, sounds like just what I need. But I thought I'd let you know it's entirely unreadable with the built-in Mac OS X "Preview" Program.
(See the Screenshot).
What PDF writer did you use?


Stange. I have OS X 10.5.7 and it looks perfect in Preview (which is the default Mac pdf viewer). My version of preview says "Version 4.2 (469.5)".

Does this work or not work for anyone else on a Mac?

I used Open Office 3.0 to save it as a PDF. I wonder if your download was corrupted. I've seen that before particularly when the machine has a virus (which might be appending itself to downloads).

_________________
-Brad
 
 View user's profile Send private message  
Reply with quote Back to top
thefool
PostPosted: May 25, 2009 - 11:06 AM
Wannabe


Joined: Nov 18, 2008
Posts: 79


I've had the exact same problem with another PDF from openoffice, maybe it doesn't stick to the standard...
I'm using Mac OS X 10.5.6 and Preview 4.1 (469.4)
I'll update my system and see if the error is resolved.

You've actually seen a virus infected Mac? What virus was that? (Or are you talking about a PC with similar symptoms?)
 
 View user's profile Send private message  
Reply with quote Back to top
thefool
PostPosted: May 25, 2009 - 11:33 AM
Wannabe


Joined: Nov 18, 2008
Posts: 79


OK, updated to 10.5.7 (and Preview 4.2) and it's perfectly readable now. I guess there was an error in Preview 4.1...
 
 View user's profile Send private message  
Reply with quote Back to top
schickb
PostPosted: May 25, 2009 - 03:34 PM
Hangaround


Joined: May 07, 2007
Posts: 291
Location: Seattle

thefool wrote:
You've actually seen a virus infected Mac? What virus was that? (Or are you talking about a PC with similar symptoms?)
PC with similar symptoms, but there are Mac viruses.

Anyway, glad updating your system helped. Hope you find the FAQ useful.

_________________
-Brad
 
 View user's profile Send private message  
Reply with quote Back to top
thefool
PostPosted: May 26, 2009 - 10:49 PM
Wannabe


Joined: Nov 18, 2008
Posts: 79


schickb wrote:
there are Mac viruses.

I know, I've just never actually witnessed one Smile

schickb wrote:
Hope you find the FAQ useful.

Very much so, thanks a lot for that!
I'm just writing a bootloader and was wondering about the things you adressed in 10. and 11. So you've helped me understand quite a bit more!
 
 View user's profile Send private message  
Reply with quote Back to top
Display posts from previous:     
Jump to:  
All times are GMT + 1 Hour
Post new topic   Reply to topic
View previous topic Printable version Log in to check your private messages View next topic
Powered by PNphpBB2 © 2003-2006 The PNphpBB Group
Credits