AVRGCC Linker Script Question

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

LwMesh v1.1.1 had two example projects that could be used for OTAU (/apps/Bootloader and /apps/OTAServerDemo.

 

 

These were removed in later versions of the stack.  Unfortunately, the examples only supported the ATMEGA1281 and the ATMEGA128RFA1.  I am trying to make the minimum number of changes to get them to support the ATMEGA256RFR2.

 

I finally got the bootloader app to compile "successfully", but the last mod I had to make was to a linker script.  Specifically, there was a line that was causing problems:

 

Was:

OUTPUT_ARCH(avr:5)

 

Changed to:

OUTPUT_ARCH(avr:6)

 

I have absolutely no experience with linker scripts.  My mod was a bit of a lucky/educated guess based on the error messages I saw when compiling.  The complete script is attached (changed from .ld to .txt).

 

Was my mod "correct"?  What is the significance of 6 vs. 5?

 

What would be some good sources for learning more about linker scripts (looking for more than "google it" answers here).

 

Thanks in advance.

 

 

Attachment(s): 

Science is not consensus. Science is numbers.

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

The architecture types are because there are several varieties of AVR: chips with single byte stack pointers, chips with and without multiply instructions, and so on.

They're described here: http://www.nongnu.org/avr-libc/u...

(It's not really a linker-script specific thing, but the linker does need to know which chip you're using in order to get the right libraries and etc.)

 

As for a m256rfr2 bootloader, modifying an existing 128rfa1 linker script to a different OUTPUT_ARCH() makes me really nervous.  The 256k parts have significant linking differences from the 128k parts (3 bytes for PC!), and you'd probably be better off taking the default 256rfr linker script and adding whatever changes were needed for the 128rfa chip, if you need a linker script at all.

 

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

From the standard toolchain linker scripts, the primary difference I see is the starting address of data (start of SRAM in the data address space). For avr5, it is at 0x800060, whereas for avr6, it is 0x8000200. In the linker script you attached, the ORIGIN is set to 0x00800190. which looks wrong.

 

It should work ok otherwise, as long as the source files were compiled with the right flag, and the right libraries were linked.

Regards

Senthil

 

blog | website

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

"avr6" also needs to use ELPM while "avr5" just uses LPM.

 

While the layout of the current manual is a bit muddled you can kind of see that here:

 

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

 

avr5 AVR_ARCH=5
AVR_MEGA [5]
AVR_ENHANCED [5]
AVR_HAVE_JMP_CALL [4]
AVR_HAVE_MOVW [1]
AVR_HAVE_LPMX [1]
AVR_HAVE_MUL [1]
AVR_2_BYTE_PC [2]

avr6 AVR_ARCH=6
AVR_MEGA [5]
AVR_ENHANCED [5]
AVR_HAVE_JMP_CALL [4]
AVR_HAVE_MOVW [1]
AVR_HAVE_LPMX [1]
AVR_HAVE_MUL [1]
AVR_HAVE_RAMPZ [4]
AVR_HAVE_ELPM [4]
AVR_HAVE_ELPMX [4]
AVR_3_BYTE_PC [2]

In common they have "MEGA", "ENHANCED", "HAVE_JMP_CALL", "HAVE_MOVW", "HAVE_LPMX", "HAVE_MUL"

 

But the avr6 (>128K) then differs in having "HAVE_RAMPZ", "HAVE_ELPM", "HAVE_ELPMX" and "3_BYTE_PC" instead of "2_BYTE_PC"

 

This is why you cannot link a .o file built for "avr6" against other .o or .a files built for "avr5" because one block of code may need to handle RAMPZ and use ELPM in place of LPM and some may be assuming pushed CALL's use 3 bytes on the stack while the other code has just 2.

 

So code for xxx256 devices has to be recompiled from scratch - you cannot just link against code already built for "avr5".

 

There are actually 17 different avrXXX architectures and you cannot mix (prebuilt) code between any of them.

 

This is also why you pass -mmcu=xxxxx to both the compiler and the linker - both need to know to get "avrXXX" correct.

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

Thank you for all the great responses.

 

I suspected just changing that one field was not the correct solution.  I am still digesting the information provided.

 

I also found this thread: https://www.avrfreaks.net/forum/lightweight-mesh-otau, where Alex provided a linker script for the ATMEGA256RFR2.  That solves this immediate problem, but I know that others will arise....

Science is not consensus. Science is numbers.