no "manual" jump to bootloader section ?

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

Hi

I just got my bootloader for a xmega128a1 device running but there is one thing that is not working. Like in another bootloader for a mega1280 I'd like to have the option to trigger the bootloader from within the code. So in my mega1280 project I set my flag in eeprom which activates the bootloader and then just jump to the bootloader section with this :

void (*boot)(void)=0xF000;

boot();

with the xmega (and address 0x10000) this doesn't work. I also tried to set the EIND = 0 but no difference. Did I miss something there in the datasheet, or can anyone explain what's wrong ?
Thanks a lot,
Mat

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

Which C compiler? I just built this in GCC for mega1284 (I just happened to have it selected):

#include 

void (*boot)(void)=0xF000;

int main(void) {
	boot();
	while(1) {
	}
}

The generated code was:

int main(void) {
	boot();
  be:	e0 91 00 01 	lds	r30, 0x0100
  c2:	f0 91 01 01 	lds	r31, 0x0101
  c6:	09 95       	icall
  c8:	ff cf       	rjmp	.-2      	; 0xc8 

When I stepped that in the simulator control went to word address 0xF000 as you intended.

(but I thought Xmega's had a separate area for the bootloader above the normal flash space - or have I got that wrong?)

BTW, looking at the opcode manual it seems EICALL (rather than ICALL) only comes into play with devices above 128KB of flash in which case PC(15:0) is loaded from Z and PC(21:16) is loaded from EIND. So EIND should not be relevant to a 128KB device.

Certainly, as the code above generates ICALL any setting of EIND will be irrelevant as PC(21:16) are set to 0 by ICALL on >128KB devices.

BTW Another way to do long jumps would be (on 24 bit PC processors) to push the 3 bytes for the destination then RET.

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

yes, it's GCC, and just as you (and I) wrote this works with a mega1280 or 1284.

Now I'm a little confused, don't they all have seperate areas for a bootloader (megas AND xmegas) ?

About the EIND : I was a little ashamed to ask before, I also read about the 128k thing but my bootloader will not jump to application start if this EIND is not set to 0. I don't know why yet. That's why I thought this could help in the other direction too.

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

Well I just went to this page:

http://www.atmel.com/dyn/product...

to download the two datasheets to refresh my memory. In the 64A1/128A1/192A1/256A1/384A1 document there's an interesting table in Figure 7-1 which seems to verify that each device has a separate 8K (apart from 64A1 which has 4K) separate from the main flash array. In the 128A1 case this means it is based at word addresses 0x10000 to 0x10FFF.

So all looks good until you search the entire document for "bootloader" when you hit:

Quote:
35.2 ATxmega128A1 rev. G
• Bootloader Section in Flash is non-functional

If that's true that would be rather sad for you :-(

By the way you started this therad with:

Quote:
I just got my bootloader for a xmega128a1 device running

what do you mean by "running" and at what address?

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

my make file puts the bootloader in the bootloader section and the reset fuse is set to jump to the bootloader and it does. The Bootloader code runs and loads the application code. The only thing that doesn't work is the jump to the 0x10000 address to manually restart the bootloader. (there is an eeprom flag deciding wether to bootload or start the application). The jump from the bootloader to the application section at 0x0 works. I just tried the software reset, this does the job also but I wonder why the jump to the bootloader works in the mega1280 and doesn't in the xmega128a1

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

Quote:

my make file puts the bootloader in the bootloader section

But at WHAT address? As I say it looks to be word address 0x10000 which is byte address 0x20000 which is 128KB.

In your first post you showed an attempt to jump to word address 0xF000 not 0x10000?

But that errata seems to suggest that boot flash simply doesn't work in 128A1?

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

it's byte address 0x20000.

in the first post I mentioned the working code for the mega1280 where the bootloader is at byte address 0x1E000. So the jump from the code is to word address 0xF000

where do I find out the rev. no. ? maybe I have rev. H ?

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

OK so I built this in the simulator for 128A1 and it seems to do what you required (gets to word address 0x10000):

#include 

void (*boot)(void)=0x0;

int main(void) {
	EIND = 1;
	boot();
	while(1) {
	}
}

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

although you talked about it it took a while until I really realised the 128k issue. :oops: Of course I forgot to set the EIND = 1 for the 17bit address I wanted. Thank you once again clawson !

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

I think the xmega256 (and larger devices) have an extended long jump instruction that will reach beyond 128k. The xmegas have their boot flash in a separate section that does NOT make use of application space. SO an xmega128 really has MORE than 128KB of flash. (setting the boot reset fuse must do something funky in allowing the reset vector to imply the 17th bit). BTW if your boot reset fuse is enabled you can always use the software reset function in your application to get into the boot loader.

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

yes, thank you, that's what I didn't get before, that mega1280 has the 128k including bootloader section and xmega128 has 128k for application and then the extra 8k bootloader section.
and yes, as written somewhere above the software reset was my alternative plan, but I wanted to know what was going on with the address jump.

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

Quote:

I think the xmega256 (and larger devices) have an extended long jump

As shown here its actually the 128+ devices that have EICALL/EIJMP for the very reason of this B/L section beyond the 16th bit. In GCC this architecture is known as avrxmega7. From "avr-gcc --target-help":

AVR options:
  -mmcu=[avr-name] select microcontroller variant
                   [avr-name] can be:
                   avr1  - classic AVR core without data RAM
                   avr2  - classic AVR core with up to 8K program memory
                   avr25 - classic AVR core with up to 8K program memory
                           plus the MOVW instruction
                   avr3  - classic AVR core with up to 64K program memory
                   avr31 - classic AVR core with up to 128K program memory
                   avr35 - classic AVR core with up to 64K program memory
                           plus the MOVW instruction
                   avr4  - enhanced AVR core with up to 8K program memory
                   avr5  - enhanced AVR core with up to 64K program memory
                   avr51 - enhanced AVR core with up to 128K program memory
                   avr6  - enhanced AVR core with up to 256K program memory
                   avrxmega3 - XMEGA, > 8K, <= 64K FLASH, > 64K RAM
                   avrxmega4 - XMEGA, > 64K, <= 128K FLASH, <= 64K RAM
                   avrxmega5 - XMEGA, > 64K, <= 128K FLASH, > 64K RAM
                   avrxmega6 - XMEGA, > 128K, <= 256K FLASH, <= 64K RAM
                   avrxmega7 - XMEGA, > 128K, <= 256K FLASH, > 64K RAM
                   or immediate microcontroller name.

Note the "> 128K, <= 256K FLASH" for avrxmega7 in that. IOW the 128K Xmega really have "> 128K".