[FAQ] [C] (writing a) Bootloader FAQ

Go To Last Post
83 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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 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)

Attachment(s): 

-Brad

Last Edited: Tue. May 19, 2009 - 05:58 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is great

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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:

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 */

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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/resourc...
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: Tue. May 19, 2009 - 04:04 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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 ;)

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: Tue. May 19, 2009 - 06:06 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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/resourc...
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.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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 ;)

-Brad

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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/product...

So speciality AVRs would be Automotive AVR, Lighting AVR, AVR Z-Link, Battery Management AVR, CAN AVR, USB AVR and LCD AVR.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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 ;)

-Brad

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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. ;-)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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?

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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?)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

schickb wrote:
there are Mac viruses.

I know, I've just never actually witnessed one :-)

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!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

AndersAnd wrote:
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?

Why you not look on the projects page?

Bootloader for ATtiny13 ... ATmega2561:

http://www.avrfreaks.net/index.p...

Peter

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I'm not able to download the pdf file. The browser is pointing to index.php,

Leo;

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hayashi_leo wrote:

I'm not able to download the pdf file. The browser is pointing to index.php

It still works find for me. I assume you are clicking the "Download" link in the very first post on page 1 of this topic. You can also try right clicking that link and selecting "save link as".

-Brad

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The board used to have this problem but if the downloaded file gets called index.php just rename it to boot.pdf and it should still work

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks! it works!!

Leo;

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

danni wrote:
AndersAnd wrote:
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?

Why you not look on the projects page?
Bootloader for ATtiny13 ... ATmega2561:
http://www.avrfreaks.net/index.p...

Thank's for the heads up Peter, I missed that.
Does this bootloader use a software UART for all devices?
ATtiny13 and ATtiny45 doesn't have hardware UART, ATtiny2313 is the only ATtiny with UART.

AVR-----------user size--programming time
-----------------------------------------
ATtiny13-------606 Byte---0.77 seconds
ATtiny2313----1630 Byte---2.86 seconds
ATtiny45------3646 Byte---3.52 seconds
ATmega8-------7680 Byte---1.81 seconds
ATmega16-----15872 Byte---3.35 seconds
ATmega32-----32256 Byte---5.33 seconds
ATmega644----64512 Byte---8.19 seconds
ATmega2561--261120 Byte--32.75 seconds

At what BAUD-rate is this measured?

I guess "user size" is the same as the maximum program space flash left with the bootlaoder installed?
So this bootlaoader takes up this much flash in the different devices:

AVR-----------user size--------bootlaoder size------
----------------------------------------------------
ATtiny13-------606 Byte----1*1024-606    =  418 Byte
ATtiny2313----1630 Byte----2*1024-1630   =  418 Byte
ATtiny45------3646 Byte----2*1024-1630   =  450 Byte
ATmega8-------7680 Byte----8*1024-7680   =  512 Byte
ATmega16-----15872 Byte---16*1024-15872  =  512 Byte
ATmega32-----32256 Byte---32*1024-32256  =  512 Byte
ATmega644----64512 Byte---64*1024-64512  = 1024 Byte
ATmega2561--261120 Byte--256*1024-261120 = 1024 Byte 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
typedef void (*PF_VOID)(void);
typedef void (*PF_WHATEVER)(uint8_t);

...

static __inline__ void call_func3(uint8_t arg)
{ ((PF_WHATEVER) (0x3FE2/2))(arg); }

What are functions like this called, and how do I create them for functions that need multiple parameters? Thanks, and great tutorial.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jgiers wrote:
Quote:
typedef void (*PF_VOID)(void);
typedef void (*PF_WHATEVER)(uint8_t);

...

static __inline__ void call_func3(uint8_t arg)
{ ((PF_WHATEVER) (0x3FE2/2))(arg); }

What are functions like this called, and how do I create them for functions that need multiple parameters? Thanks, and great tutorial.


Those are call function pointers. Here is an entire tutorial about function pointers in C/C++ http://www.newty.de/fpt/index.html

To add more parameters, just add them to the declaration and the call. The declaration would look something like

typedef void (*PF_WHATEVER2)(uint8_t, uint8_t);

-Brad

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi;

question for FAQ #8, Can a bootloader use interrupts?

I would like to use interrupt with USART on my bootloader rather than polling.

So before the bootloader main(); I set
MCUCR = (1<<IVCE);
MCUCR = (1<<1VSEL);

this allocates the interrupt table into the BLS.

my question is how to restore the interrupt table to the application section?

is this the right method? place this code before jumping to application section;

MCUCR = (1<<IVCE);
MCUCR = (0<<IVSEL);

??

Thanks!!

Leo;

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

hayashi_leo wrote:

my question is how to restore the interrupt table to the application section?

is this the right method? place this code before jumping to application section;

MCUCR = (1<<IVCE);
MCUCR = (0<<IVSEL);


That should work, although shifting zero isn't going to do anything. The code below is the same as yours. See faq #11 for an example of this:

MCUCR = (1<<IVCE);
MCUCR = 0;

If you want to be sure to clear only the IVSEL bit you'll need:

MCUCR = (1<<IVCE);
MCUCR &= ~(1<<IVSEL);

But you'll need to make sure the second write finished within 4 instructions of the first write (look at the ASM to know). The compiler should reduce "~(1<<IVSEL)" to a constant, and you'll be fine. But check to be sure.

-Brad

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks!!!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I didn't find Download in this post.
Thanks!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

HGunther wrote:
I didn't find Download in this post.
Thanks!

There are so many posts in the thread so that it is divided into two pages. At the top and bottom of the pages there are page selectors. Click the "1" and in the ultimately first post there is an attachement.

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Also note that I don't think your see attachments if you are not logged in. But the first post definitely has a PDF in it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:

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

Well we did... We had a bogus bootloader in a mega32?. (something with interrupts still enabled during programming). So sometimes it would not update correctly and the system would hang, luckily we could reboot it remote and re-upload the software.
So this is (roughly) what we did:
We figured out where our SPM function was.
Created special software containing a new bootloader as payload.
Used the existing bootloader to upload it.
Using the existing SPM function to flash a new SPM function to the end of the bootloader section.
Use the new SPM function to update the entire bootloader.
Reboot and let the bootloader load the normal software.
Yes it involved hard coded addresses, some special tricks to harden the flow against powerdowns etc. There was only one moment where we could not recover if we should have had a power failure.
It was some pretty nasty coding, but we now have a defined SPM function at the very end of our bootloader. And the bootloader has at least one bug less ;)

We also did bootloaders for Atmega48. (we did multiple actually) The code to do it is dead ugly and I was looking for pretty ways of doing it when came across this topic. Just wanted to let you know.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm attempting to write my first bootloader and this the best explaination I've seen so far on the subject. However I have a question about setting up the environment to compile one. I use AVR Studio with a WinAVR installation, and have never had to muck around with the make files. Is there a way to specify to AVR Studio what changes need to be made to the make file to insure the code gets placed at the proper base address?

I also have another question that is outside of the scope of your fantastic document, but maybe somebody can point me in the right direction. I have a VB.NET app that communicates with my ATMEGA168, and I would like to be able to have it update the controller code if necessary. I don't expect anybody to give code examples, but if you know of any examples out in the wild, please let me know.

And thanks again for the great write up!

Wayne

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Is there a way to specify to AVR Studio what changes need to be made to the make file to insure the code gets placed at the proper base address?

Project menu
Configuration Options
Memory Settings
[Add]
Type = Flash (already selected)
Name = .text
Address = 0x1C00 (for example)
[OK]
[OK]

In this example (for mega16) I specified the address as 0x1C00 which is the WORD address for the BLS boundary address. When the code is built this can be seen as:

avr-gcc -mmcu=atmega16 -Wl,-Map=test.map -Wl,-section-start=.text=0x3800 empty.o test.o    -lm  -o test.elf

during the link. Notice how Studio has passed the 0x1C00 (word) address that was entered as 0x3800 (byte = 2* word) address because while Studio uses word addresses for flash GCC needs byte addresses.

The result of this is:

Disassembly of section .text:

00003800 <__vectors>:
    3800:	0c 94 2a 1c 	jmp	0x3854	; 0x3854 <__ctors_end>
    3804:	0c 94 47 1c 	jmp	0x388e	; 0x388e <__bad_interrupt>
    3808:	0c 94 47 1c 	jmp	0x388e	; 0x388e <__bad_interrupt>
    380c:	0c 94 47 1c 	jmp	0x388e	; 0x388e <__bad_interrupt>
    3810:	0c 94 47 1c 	jmp	0x388e	; 0x388e <__bad_interrupt>
etc.

which confirms that everything including the reset jump and the ISR vector table have been moved to byte address 0x3800

As for the VB thing I guess what you are asking is "how do I do COM ports from a VB program?" See examples written by Joe Pardue (smileymicros). I think he used to use VB and now uses C# but the M$ APIs you use are virtually identical (as is the case with all the .Net languages)

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

TracerH wrote:
I'm attempting to write my first bootloader and this the best explaination I've seen so far on the subject. However I have a question about setting up the environment to compile one. I use AVR Studio with a WinAVR installation, and have never had to muck around with the make files. Is there a way to specify to AVR Studio what changes need to be made to the make file to insure the code gets placed at the proper base address?
I've done this using the Project Options without a special makefile (AVRStudio now generates it for you) but I don't remember all the details at the moment other than that I always had to double check that the bootloader address was correct. It seemed to want to randomly reset or not remember it properly between uses. IIRC the problem was in the Memory Settings of the Project Options.

TracerH wrote:
I also have another question that is outside of the scope of your fantastic document, but maybe somebody can point me in the right direction. I have a VB.NET app that communicates with my ATMEGA168, and I would like to be able to have it update the controller code if necessary. I don't expect anybody to give code examples, but if you know of any examples out in the wild, please let me know.
Are you looking for some sort of GUI that creates the parameter list for avrdude and then calls it to upload a hex file to your bootloader? If so, I am just now tying up loose ends on a C# .NEt project that does this. I plan to post the code here in a week so be on the lookout for AVRUP-V1. Look that over and if you really need me to, I can do an auto port from C# to VB. Let's not hyjack this thread so if you are interested either start a new thread 'avrdude GUI in .NET?' or wait till I post my code.

[edit]AND along comes Cliff while I'm fumbling around.[/edit]

Smiley

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Wow, you guys are fast and informative! Many thanks for the information. Since reviewing the docs here, I have found the AVR109/AVR911 app notes. I will look at the setup in AVR Studio when I try this.

As for the VB.NET end, I will review the existing code and eagerly await the new version. (C# and VB are basically the same.) I am hoping to recreate the download code without using AVRDUDE. I am quite experienced in using the RS-232 port from .NET code, so more looking for information on parsing the hex file format for download. Maybe I can find what I need in the source to AVROSP.

So, again, my humble thanks to you guys for the speedy help. And sorry for the thread hijacking!

Wayne

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

Thanks for this tutorial! But I still have a problem concerning question #1. Not gone far yet...

I want to write a bootloader for Mega168. I set the BOOTRST and BOOTSZ to 1024 words. I use AVR Studio with WinAVR, gcc and JTAG ICE MKII.

I need to write the bootloader in the bootloader section so I did as in the FAQ. In the custom options, I added "-Wl,--section-start=.text=0x3800". When I load the code, it is still at 0x00. I look in the view memory to see where it is. I load it with the JTAG MKII using Debug Wire (start debugging).

Questions:

1- Is it ok to load a bootloader with JTAG MKII and DW?

2- If not, wich tool to use?

3- In my bootloader program, I make a normal AVR project with a "int main (void) {}" function. Is this ok?

4- Am I missing something to put the code at 0x3800 (0x1C00 word adress)?

Thanks a lot!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK, I found it. I should use more often this forum so I could find more answers myself... I read this post (did not get my attention the first time) pointing on the memory settings.

Project menu
Configuration Options
Memory Settings
[Add]
Type = Flash (already selected)
Name = .text
Address = 0x1C00 (for example)
[OK]
[OK]

Thanks to Cliff.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

1) No problem whatsoever

2) not that you have to but I'll just point out that JTAGICEmkII is also an ISP programmer and can be used very like an AVRISPmkII

3) that's EXACTLY what you should do - the BL should be a completely standalone program with its own reset vector, C pre-amble and main() function - so you build it just like any other program with the single change to the .text base address

4) Your --section-start *SHOULD* have worked (you may be interested to know that -Ttext=.... is shorthand for the same) however Studio can make this easier for you. Go to Config Options on the Project menu and select the fourth icon down on the left ("Memory settings"). Click [Add]. Leave type as "Flash". Enter ".text" for name and for the address the key thing is that this is "Atmel-speak" so the address must be in WORDS not BYTEs. You know your desired byte address is 0x3800 so half this to get the word address 0x1C00 and enter that.

The nett effect of (4) is that when the code links (avr-gcc invoked without -c) you should see that very same --section-start=.text=0x3800 that you were trying to use being passed. (in fact it will be interesting to hear how this differs from your attempt - maybe you had it on the compile rather than the link?)

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks you Cliif,

About 2)
I usually use the DW to program my devices when they only support DW (not JTAG mode like the Mega168). I have never been able to program or change the fuses with the ISP mode. I use a STK-600 to do that. Am I suppose to be able to program or set the fuses on a Mega168 with ISP?

3) That's what I've done, but because I had a hard time loading the program at the bootloadwr section, I though it could be an issue.

4) I do not have the set up here tonight, I will come back on it but now it works but I remenber that I saw the --section-start=.text=0x3800 after compiling. Is it in the complie or link section, I don't know.

Now I need to load some pages through spi (from RF an device, SI4432) and reprogram the Mega168. I may have more questions!

Thanks for your reply!

Dominic

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

2) yes, if in the connection box of AVR Studio for JTAGICEmkII you set the mode to "ISP" rather than "JTAG" then it should operate pretty much as any standard ISP programmer using the ISP pinout given in the user manual which rather confusingly refers to it as SPI rather than ISP (yes it's a form of SPI but it's usually called ISP because it may use different pins to an AVR's normal SPI). Table 3-3 shows which 6 wires from the "squid" cable to connect to the ISP header of the board being programmed:

JTAGICE mkII probe Target pins Squid cable colors SPI pinout 
Pin 1 (TCK)        SCK         Black              3 
Pin 2 (GND)        GND         White              6 
Pin 3 (TDO)        MISO        Grey               1 
Pin 4 (VTref)      VTref       Purple             2 
Pin 5 (TMS)                    Blue   
Pin 6 (nSRST)      RESET       Green              5 
Pin 7 (Vsupply)                Yellow   
Pin 8 (nTRST)                  Orange   
Pin 9 (TDI)        MOSI        Red                4 
Pin 10 (GND)                   Brown 

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So does the "non-commercial" part of the FAQ Creative Commons license mean I can't reference this FAQ for building my commercial application or I can't take the FAQ and resell it or any of its information for profit?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you are an author of a bootloader Brad and I hope that after reading this you'll have a better idea of how to go about it. Why would you need to either quote passages from the document or even attempt to sell bits of it simply to ship a device that contains a bootloader that has been authored as a result of the guidance here?

As it happens, for the parts I wrote you are welcome to use them freely and openly (I'm against restrictive licences like GPL and such myself and much prefer BeerWare/Free BSD etc). For other parts you'd need to contact Brad Schick to ask his permission. He no longer visits Freaks (AFAIK) but I can email him on your behalf and ask him to contact you if you want to PM me your email address.

(a PM to his ID here may trigger an email to him anyway)

Of course none of this precludes the copyright requirements of Atmel's Tutorial Forum which are given in the sticky at the top of this forum:

Tutorial Copyright

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Why would you need to either quote passages from the document or even attempt to sell bits of it simply to ship a device that contains a bootloader that has been authored as a result of the guidance here?
Thanks for the reply.

I'm no licensing expert and was just curious if the licensing was meant to prohibit development of commercial software based on the FAQ or just copying all or part of the text as part of commercial documentaion (the latter of which I have no intention of doing).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh no, I don't know about Brad but personally I see a LOT of similar questions cropping up here about bootloaders - often about code positioning and often about function sharing between the two halves and when Brad took the time out to try and nail some of these questions once and for all and then asked myself and others to contribute further questions and comment on/correct what he'd wrote I welcomed it in the hope that many times we could now just say "read the bootloader FAQ" rather than writing out the same --section-start=0xNNNN thing for the 1000'th time.

EDIT 1363 downloads of the .PDF suggest a bit more than 1,000 in fact!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
That flag specifies the starting byte address of the bootloader. You can find this value in the datasheet for your AVR. Make sure you use the byte address and not the word address (most Atmel datasheets list word addresses for flash regions, but some list byte addresses).

How to recognize byte address and word address?
And how to transform a word address to a byte address ?

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

How to recognize byte address and word address?

Generally, you cant discern a byte address from a word address. You just need to know the context when reading: Eg, by knowing that Atmel likes to use word addresses in most cases. Or by recognizing something you know the address of (and the actual address used is double or half of that). Etc...

Quote:
And how to transform a word address to a byte address ?

Multiply by 2 (or shift left one position, if you prefer).

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You know that the four BOOTSZ1:0 are going to select a region within 4K of the end of the chip. So take a mega328 as an example. You and I know that this has 32K BYTES of code flash. Atmel would tell you that it can hold 16K opcodes because they are 16bit WORDS. An Atmel Word is 16bits so if you talk about addressing in Words rather than 8bit bytes you halve the address. Thus the word address 0x1F27 is byte address 0x1F27*2 = 0x3E4E

Now if you dig out the 328 datasheet and look at the table that sets out the four BOOTSZ combinations. It shows:

BOOTSZ1 BOOTSZ0  Boot Reset Address (start BLS)
   1       1             0x3F00
   1       0             0x3E00
   0       1             0x3C00
   0       0             0x3800 (default)

But wait a minute, you, I and GCC think it terms of bytes, not words when talking about memory sizes and addresses. We know the 328 has 32K bytes and 32K in hex is 0x8000 with addresses 0x0000 to 0x7FFF. Yet those Atmel listed addresses are down around the 0x3??? range. So they cannot be anywhere near the last 4K of the chip as we expect BOOTSZ to be. So they must be words. So to convert to bytes double them:

BOOTSZ1 BOOTSZ0      Address (words)      Address (bytes)
   1       1             0x3F00            0x7E00 = 31.5K
   1       0             0x3E00            0x7C00 = 31K
   0       1             0x3C00            0x7800 = 30K
   0       0             0x3800            0x7000 = 28K

Obviously this example applies to a 32K AVR but I guess you can see the way to interpret things for any size of AVR. Consider it's size in bytes as a hex value. If the BOOTSZ positions you are looking at appear to be half these values they are words and need to be doubled. Use the resulting byte addresses with GCC.

NOTE: If you use AVR Studio and under "Configuration Options" need to specify a memory section address (such as positioning .text to the BLS address) then being Atmel it uses WORD addresses so for the 328 and BOOTSZ=10 you would specify 0x3E00 though when the code is built by WinAVR(gcc) you will note that it's actually 0x7C00 that is passed because Atmel know to double the value before passing it to GCC.

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok, I see.
Thank you for these very clear explanations.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This board only lets you see/download attachments when you are logged in. Given that you had to login as superAssembler to make that post did you not then see the file while logged in?

Cliff (moderator)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Sorry, I feel like blind. Where is the pdf?

In the first post, on the first page of this thread. The post has the TOC of the FAQ as it's text, and below that text there is a box with the heading "bootloader_faq.pdf", and in that box, to the right, is a link "Download".

Or did you look for it before you signed up and logged in, but not afterward? If so, then go back now and it will be there.

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Darn..I wish I had thought of that name. :?

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

We still have "superC" free, John. Go grab it! :wink:

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I had another great name but can no longer access it as it was part of the Beta site test. :wink:

John Samperi

Ampertronics Pty. Ltd.

www.ampertronics.com.au

* Electronic Design * Custom Products * Contract Assembly

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok so how does one obtain a copy of this miraculous document?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

the message says it all

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

Ok so how does one obtain a copy of this miraculous document?

By going to the first page of this thread, locating the very first post, and downloading the document at the link labelled "Download".

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK, that was very helpful. turns out the link is hidden way to the right, so unless you scroll to the right its invisible.

I have two more questions for you kind folks:

1) I'm trying to write flash with the SPM instruction on a ATMega128. Let's say I'm trying to write the 64 words (128 bytes) located at E000 in my address map. How do I set Registers 31, 30 and port RAMPZ to do that. The ATMEL docs on the subject just spin my head around and around and around...

2) Ok so I want to erase the page that holds my interrupt vectors in flash on the ATMega128.
I set bit 0 in RAMPZ to zero. I set SPMSCR with an STS instruction to 3. I load Registers 31 and 30 with zero then issue the spm instruction. Interrupts are disabled. I wait a second or two. The value of SPMSCR is still 0x3. What did I do wrong?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

1) from the mega128 datasheet:

Quote:
The Z-pointer together with RAMPZ are used to address the SPM commands. For details on how to use the RAMPZ, see “RAM Page Z Select Register – RAMPZ” on page 14. Since the Flash is organized in pages (see Table 123 on page 291), the program counter can be
treated as having two different sections. One section, consisting of the least significant bits, is addressing the words within a page, while the most significant bits are addressing the pages.
This is shown in Figure 134. Note that the page erase and page write operations are addressed
independently. Therefore it is of major importance that the Boot Loader software addresses the
same page in both the page erase and page write operation. Once a programming operation is
initiated, the address is latched and the Z-pointer/RAMPZ can be used for other operations.
The only SPM operation that does not use the Z-pointer/RAMPZ is setting the Boot Loader Lock
bits. The content of the Z-pointer/RAMPZ is ignored and will have no effect on the operation.
The (E)LPM instruction does also use the Z-pointer/RAMPZ to store the address. Since this
instruction addresses the Flash byte by byte, also the LSB (bit Z0) of the Z-pointer is used.

The key things in this are the fact that addressing is BYTE not WORD addressing and therefore Z can only access the first 64K but this can then be extended to the second page with RAMPZ. I take it by E000 you mean the word address so in byte addressing that is
1C000. So you'd set RAMPZ to 1 and Z to C000.

2) suggest you show the code but as this thread is not for diagnosing general SPM problems (only for discussing the FAQ) I suggest you do this in a new thread in AVR Forum.

BTW as for not being able to download the PDF. Do you not see the first page as:

No scrolling to the right needed for that?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

thanks for clarifying the Z pointer addressing. The document you quote sends you into three different document sections and addresses several unrelated issues. The result is that it does in fact leave the reader unclear about the z pointer addressing. I would recommend a bit oriented diagram instead of the combined diagram/word descriptions used.

I checked again and in fact if you don't know the forum, you have to be clairvoint or happen to scroll. I acatually had to use a google lookup to find it the first time.

I appoligize for posting to the wrong forum. That's why they call us newbies :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I checked again and in fact if you don't know the forum, you have to be clairvoint or happen to scroll.

I don't understand your "scroll" comment. As my picture shows the PDF link is right there within the 4" width of the page view?!?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I can not make the download link "invisible" (scrolled out) unless I also make half the text or so also scrolled out to the right. DUT: Firefox 3.6.13.

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

i want basic sample program for boot loader in c
can you give link or any think which helps to start

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Which C compiler? If GCC then study this:

http://www.nongnu.org/avr-libc/u...

The "API Usage Example" there is almost everything you need to get started.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi !

When we want to self-program the flash, we've two alternatives :
1) fill the buffer before a Page Erase
2) fill the buffer after a Page Erase

If i choose the first alternative, can i use the boot_page_fill() function anytime in the program (but before boot_page_write(), of course) ?

e.g : while the number of words received ! = SPM_PAGESIZE, boot_page_fill(word_address, word) ans when number of words received == SPM_PAGESIZE, erase and write page.

Can I do that?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi
I'm afraid I too am having problems accessing this pdf.
First I could not see the box at the bottom of the first item but after logging in sure enough after scrolling miles to the right there it was. (its as if the box is two normal page widths wide). Anyway clicking on down load I get a loading bargraph at the bottom of the page and then a complete blank except for an odd icon in the top left hand corner of the screen. I am using Nitro pdf reader. Its been ok so far on all other pdf's Ive downloaded - and there are many.....
Any ideas?
Dave H

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

after scrolling miles to the right there it was. (its as if the box is two normal page widths wide)

The box is always as wide as the page is, i.e. as wide as the widest post in the current page. If the page is "wider than reasonable" then it might be due to

- Someone having produced a post that makes the page very wide (long line that can not be broken i.e. no spaces etc, or large/wide picture attached), or

- The browser used has some quirk rendering pages. Right now I'm typing this with FireFox, and the page fits on a 1280 wide screen. Mind you, I have clicked the Maximize link (no not any button on the browser window title bar os similar - there is a link at the top of every AVRfreaks page). This simple manouvre lets you utilize the whole browser window width for something useful, rather than wasting perhaps half of it on some green goo that someone at Atmel decided he could use my presious and expensive screen pixels to display.

Quote:
Any ideas?

Try another browser?

"He used to carry his guitar in a gunny sack, or sit beneath the tree by the railroad track. Oh the engineers would see him sitting in the shade, Strumming with the rhythm that the drivers made. People passing by, they would stop and say, "Oh, my, what that little country boy could play!" [Chuck Berry]

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well I think I've cracked it, (not being able to download the TUT)
I used my wifes laptop running XP and with Adobe Acrobat reader, (on my computer I use Nitro pdf reader which has worked perfectly up to now), and although the page for this post is VERY WIDE (? only when logged in) by scolling to the right I get to the download link and pressing this loads up the pdf. (with my PC all I got was a blank page)

Well I have to say it was well worth the effort!
I take my hat off to those who put in the time and effort to compile these pearls of information in such a reasoned and logical and concise way - even I understood half of it - fortunately the relevent half.

Thanks again
Dave H

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'd like to suggest a modification to the tutorial. For people who are trying to learn about bootloaders, this tutorial doesn't have much of an explanation of the higher level concepts. It's definitely a good reference after you've learned the basics, but we don't have a guide to help people get to that point. I just went through this process so I thought I'd point this out while it's fresh in my mind.

The biggest stumbling block I've seen in countless threads as well as experienced is the leap from putting the bootloader on the mcu and then actually using it. Every document I've seen for AVR Dude, avrfreaks tutorials, posts, etc. has people asking the same questions. Simply put, a section titled "This is how you actually use the bootloader (with examples)" would have saved me many hours of trying to understand what comes next. This tutorial has a one-liner with no specific information, which didn't really help me at all.

Quote:
Two step approach: Program your bootloader with an external programmer as described in question #6. You will probably also want to set fuses, including BOOTSZ and BOOTRST, at the same time. Then simply use the bootloader's normal communication mechanism to transfer and program the application.

That's great and all, but if you don't know how to use it in the first place, this statement only frustrates you more.

I'd be happy to work on this if you acknowledge that it would be put in the FAQ if I provided it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

We didn't write this for beginners. It's for those actually interested in WRITING a bootloader. They are bound to know how you use one!

Feel free to start a new tutorial thread with a beginners guide to using bootloaders - all contributions welcome here.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
We didn't write this for beginners. It's for those actually interested in WRITING a bootloader. They are bound to know how you use one!

Feel free to start a new tutorial thread with a beginners guide to using bootloaders - all contributions welcome here.

Don't you think it would be good if it could be combined into one resource for everyone to reference? I don't think it's a complicated enough topic for two. The beginner stuff could simply be an introductory section that advanced users could skip.

If I started a thread for beginners, the name would likely be confusing since this one doesn't really mention that it is for writing bootloaders. Bootloader FAQ implies a broader scope than creating one. When I was trying to learn about bootloaders, this seemed like a good place to start, so I read most of the document hoping it would have something beginner friendly.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hmm. SELFPGMEN or SPMEN is our indication that flash memory is "busy", and careful bootloaders loop waiting for this to be "self cleared" to indicate that an SPM instruction may be used.

But documentation also says that "The CPU is halted during the entire Page Write operation if the NRWW section is addressed" and similar.

On a chip that does not have a RWW section, will code EVER see a non-zero value of SPMEN? It sounds like the CPU would be halted for the entire duration that it would be set...

(Looking at RalphD's tiny asm version of optiboot. Not checking SPMEN is one of the optimizations.)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Great write up!  It was my primary source for getting my wireless version of the AVR231 bootloader going.

 

Maybe it's obvious, but I would make one suggestion--provide a little detail on how to define ADDR_APP_RUN referenced here:

 

// Bootloader code
const uint8_t app_run = eeprom_read_byte(ADDR_APP_RUN);
if(app_run == APP_RUN)
{
// In case the app is faulty, clear the eeprom byte so that
// the BL will run next time. A properly running app should
// set this back to APP_RUN.
eeprom_write_byte(ADDR_APP_RUN, 0xFF);
run_application();
}
// Only run the bootloader once, then go back to the app
// (comment out the next line during app development)
eeprom_write_byte(ADDR_APP_RUN, APP_RUN);

I don't think you can just  #define or hardcode ADDR_APP_RUN to something like 0x0 in a header file shared between the bootloader and application.  The compiler will assign one of your application variables to the same eeprom address.  For example, in my application code I have statements like this:

 

uint8_t EEMEM ee_ReceiveA=RF_CHANNEL_A

The compiler can assign whatever address it wants to ee_ReceiveA--it will likely be 0x0 if that's the first EEMEM variable you define.   

 

If the  bootloader has something like this:

 

uint8_t EEMEM ee_app_run

then one can look up the address of ee_app_run from the booloader map or .lss and access the associated eeprom data in both the bootloader and application using that fixed address. 

 

But, doesn't something also have to be done in the application to reserve a EEMEM byte at that same address?  One could declare ee_app_run before any other EEMEM variables in both the application and bootloader code.  But, is it OK to depend on the linker to put the first EEMEM declared at 0x0?

 

What's the recommended way to define an ADDR_APP_RUN and share it between the bootloader and application code?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You are quite right. No one should ever be using absolute addressing in the EEPROM. You don't do it with variables in RAM - you just place them by name and the linker finds addresses for them. That should be true for EEPROM too. So he should have had something like:

uint8_t app_run_inEE EEMEM;

Then pass &app_run_inEE as the address parameter to the eeprom_*() functions. Good spot.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, but then how do you reference that same address in EEPROM in the application which is built and compiled separately??

 

I think one must use absolute EEPROM addressing in this case, no?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yeah, I guess. In which it's probably safest to simply use the last byte/word in the EEPROM

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
"I guess.."

I hear you. It "feels wrong" to use an absolute address. At least I didn't have to answer the questionL
 "Why would you ever want to define an address for variable in EEPROM". smiley

If you think about it, application code can NEVER be independent from the bootloader code, IF you want the ability to initiate load of new code from the applicaiton (I do).

The application code and bootloader code have to have a common understanding of the mechanism used to initiate load of the new code, regardless of what that mechanism is.  
In this case, the mechanism jis a location in EEPROM, but regardless of the mechanism, since both pieces of code have to understand the mechanism, they can't be totally independent.

So, given that they can't be independent, wouldn't it make sense to always build them together?  Maybe use some linker mechanism to locate the application code at 0x0 and the bootloader code at the address defined by the BOOTSZ fuses?
  
That way you wouldn't have to fix an address for the "shared" EEPROM address.

Good practical suggestion, though.  Use the highest EEPROM address and everything should be OK.  I used the lowest and ended up "getting bit".  

Last Edited: Thu. Mar 19, 2015 - 03:00 PM