Downloading bootloader address for ATxmega

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

I have created bootloader referring AVR2054 application note for ATXmega192C3 custom board.  As per datasheet the bootloader starts at word address 0x18000. so i have used -Ttext = 0x30000 in linker settings in my Microchip studio project. But it downloads only at 0x000000 and overwrites my application software.

I also tried .text = 0x30000. However, here it gives me compilation error as below:

 

address 0x611be of Bootloader.elf section `.text' is not within region `text'Bootloader.elf section `.data' will not fit in region `text'address 0x611be of Bootloader.elf section `.text' is not within region `text'region `text' overflowed by 192974 bytescollect2.exe(0,0): error: ld returned 1 exit status
        make: *** [Bootloader.elf] Error 1

 

somehow, it does not understand that this should go in bootloader region. do i have to do any specific settings to make microchip studio understand this memory area?

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

Show the start of the .hex file that was created when you used -Ttext=0x30000. You would expect to see it start with an 03 record to offset the base. It's possible you may be using some programming software that does not correctly handle such an 03 record ?

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

When i used -Ttext = 0x30000 it gives me compilation error in Atmel studio as i mentioned. 

When i used 0x18000, the hex file starting code is  - ":020000023000CC". 

I used Atmel studio to download this file.

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

 

If I use:

 

 

and:

 

 

and:

 

 

then I get:

 

 

and in the HEX file I find:

 

 

As you also found the first record is:

:020000023000CC

I was wrong about it being an 03, it is an 02 (for details see: https://en.wikipedia.org/wiki/In... ). But the fact is this adds a 0x0030nnnn offset to following records.

 

Last Edited: Wed. Nov 10, 2021 - 12:59 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


Thanks @clawson, i could sort our the issue to some extent. I found that in device programming window there is option of "Erase Flash before programming" was checked.

 

So when i download bootloader it use to erase application and directly start bootloader. Hence i was under impression that bootloader overwrites application. Now i have unchecked this option and use 'Erase Now' option at the top of it after selecting either 'Erase Application' or 'Erase boot' on left side of the button 'Erase Now'. I have also programmed Fuse byte 2 to 'BOOT RST' so that it should boot from bootloader. However, i found that bootloader's jump function is not working and application does not start.

I have taken reference code of bootloader jump function as below from AVR2054:

 

static inline  void jumpToApplication(void)

{

#if (defined(ATSAMR21E18A) || defined(ATSAMR21G18A))                                                            //these are not defined in my code

  uint32_t appEntryPoint = *(uint32_t *)(FLASH_END_ADDRESS - sizeof(uint32_t) + 1);

  void(* startAddress)(void) =(void(*)(void))(*(uint32_t *)(appEntryPoint + sizeof(uint32_t)));

  __set_SP(*(uint32_t *)appEntryPoint);

#else

  void(* startAddress)(void) =(void(*)(void))NULL;                                                                     

#endif

  // nulling extended indirect register for indirect call out memory

  CLEAR_EIND();

  startAddress();                                                                                                                         //this is not working. as i understand it is suppose to jump to 0x000000 of flash

}

 

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

The usual approach is to build bootloader (boot.hex say) and build the application (app.hex) then to join the two programs as one file (combined.hex) and program that. It is very unwise to approach this with switching off chip erases before programming. To join the hex there's a manual approach and an automated approach. For manual you simply dump the contents of boot.hex at the end of a copy of app.hex and take out the very last line that came from app.hex:

:00000001FF

The automated way is to put a post build step in that uses the srec_cat that comes with Studio 7 to join the two .hex into combined.hex (or whatever you want to call it).

PradeepPatel wrote:
//this is not working. as i understand it is suppose to jump to 0x000000 of flash
Well it should assuming CLEAR_EIND() really does hat the name suggest. The bootloader is beyond the 128K byte (64K word) boundary so when the bootloader is running EIND will be non-0. The idea is that CLEAR_EIND will set it back to 0 and then the 16 bit function pointer indirection will take it to 0x0000 in the EIND=0 region.

 

To be honest (because that micro will have 24 bit JMPs and CALLs) I'd be tempted to replace:

  CLEAR_EIND();

  startAddress(); 

with simply:

asm("JMP 0");

then you don't need to worry about the EIND handling.

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

We want to have a separate application and bootloader hex file. During production only bootloader will be programmed in the custom board. When the final product is shipped to user and user power it up for the first time it will update the latest application hex using PC software through serial port on the custom board in final product. 

 

asm("JMP 0") - this does work.

 

Now i have started including other part of the bootloader logic to receive .srec file from PC software over serial port and flashing the same. I am facing some issue here. Investigating further i noticed that when i build bootloader without .text=0x18000 i.e. downloading at 0x00000 of flash, it works perfectly (without writing received data in internal flash memory). When i say works perfectly means it communicates with PC software over serial port and receive data (.srec file) and also send acknowledge bytes for each packet after checking CRC.

But when i build same code with .text=0x18000 it only responds to starting handshake signal and thereafter it does not respond with acknowledge bytes. Do i have to make any other settings if i build my code with .text=0x18000?

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

You're putting an SRecord decoder in the AVR? Why on earth don't you simply send binary (do srec to bin conversion on PC)

 

0x18000 is surely the word address? On a 192K micro the byte address is 0x30000, that is 3 lots of 64K.

 

The bootloader may appear to receive data at that address but it won't be able to SPM

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

 

SRecord file format is as supported by Bootloader PC tool provided with AVR2054. I am using the same tool instead of creating anything new. As per AVR2054 documentation this tool only supports .srec files. 

0x18000 is a word address as mentioned in the datasheet.

But i think there is some issue here, because if i put .text=0x30000 (byte address of 0x18000) then compiler shouts and give me error saying i am exceeding the flash limits but when i put .text=0x18000 then code compiles properly and even hex file is generated properly with below line as first line in hex file. 

":020000023000CC"

In above line 3000 (before last two characters CC) is address which when multiplied by 16 gives address value as 0x30000 which forms the base address for other lines in hex file. I hope my understanding is correct here.

But when i download this file my code does not get executed properly. When i start PC tool and try to download application .srec file, the handshaking is successful but when first line S0 record is sent by PC tool to board over serial port, at the receiving end it missed receiving some bytes of record and hence fails in checksum verification. 

However, when i download same code without building with .text=0x18000 (i.e. removing this line from linker settings) everything works properly.

 

Last Edited: Fri. Nov 12, 2021 - 08:36 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But 0x30000 is THE RIGHT ADDRESS for a 192K Xmega192?! I used it above. If you get errors then you probably have your build target set to the wrong thing. See 2nd and 3rd pictures in my post #4 above. 

Last Edited: Fri. Nov 12, 2021 - 11:13 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


You are correct...I was setting .text=0x18000 as below in memory settings which creates correct hex file. But if i set .text=0x30000 here then it gives compilation error.

 

if i set the way you have given in miscellaneous settings as -Ttext=0x30000 then it creates correct hex file without compilation error.

 

I could also found issue of data not getting properly received over serial port on custom board from PC tool. However, i could not get logical reasoning for this issue.

the code creating problem was as below:

switch (dataBuffer.recordType)

  {

      

    case SR0: // the address field is 2 bytes

    case SR1:

    case SR5:

    case SR9:

        addressLength = 2;

      break;

    case SR2: // the address field is 3 bytes

    case SR8:

        addressLength = 3;

      break;

    case SR3: // the address field is 4 bytes

    case SR7:

        addressLength = 4;

      break;

    default: // unsupported type

    {

      return false;

    }

   }

 

if i change above code in terms of if - else then it works perfectly:

if((dataBuffer.recordType == SR0) || (dataBuffer.recordType == SR1) || (dataBuffer.recordType == SR5) || (dataBuffer.recordType == SR9))

        addressLength = 2;

else if((dataBuffer.recordType == SR2) || (dataBuffer.recordType == SR8))

        addressLength = 3;

else if((dataBuffer.recordType == SR3) || (dataBuffer.recordType == SR7))

        addressLength = 4;

else

        return false;

 

My optimization level is set as -O1 and build is set as 'Release'.

Not sure why 'switch -case' didn;t worked only when bootloader is downloaded to 0x18000 but it worked correctly when bootloader was downloaded to 0x00000 of flash memory

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

Oh if you are going to use that stupid "Memories" section then you MUST read the lengthy comment on the dialog which explains how Atmel (now Microchip) want to really f*** with your mind (yes they really do double what you type in here IFF you are setting a flash address).

 

It is much easier to ignore the Atmel nonsense and just put a Ttext into the Linker's "Miscellaneous" settings and then you can use the byte addressing that God intended for computer memories.

 

Having said that if you do put ".text=0x18000" in the Memories it should have come out as a "-Wl, -section-start=.text=0x30000"in the build which should have worked.