Locating a progmem block

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

Using avr-gcc and avr-ld is it possible to control the address of a block within flash? I'm testing something written using the Atmel assembler and it does something like:

.ORG 0x800

to position a block "progmem" data. Looking at the code, the specific address doesn't matter but lots of code assumes the block is aligned on a 0x00 lo8 boundary.

I found this quote below in the avr-libc docs:
Note that .org is available in gas as well, but is a fairly pointless pseudo-op in an assembler environment that uses relocatable object files, as it is the linker that determines the final position of some object in ROM or RAM.

Is there some other way to tell the liker the exact position or a progmem block? Or even better, a way to force a certain alignment and let the linker relocate it otherwise?

-Brad

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
//avrN.x linker script
...  
/* added line start */
. = DEFINED(LD_PROGMEM_ALIGN) ? ALIGN(LD_PROGMEM_ALIGN) : . ;
/* added line end */
*(.progmem.gcc*)
*(.progmem*)
. = ALIGN(2);
...

//need linker symbol passed
-Wl,--defsym=LD_PROGMEM_ALIGN=256
//if symbol not passed, no special alignment
//so you can leave script file alone, and use
//alignment as needed

you could start messing around with moving the progmem section around, or create your own section, etc., but you are probably going to waste space somewhere with that alignment, so leaving progmem where it is may be easiest, and the wasted space will stay consistent, as the vector table will not change (progmem will always be at 0x0100 in this case).

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

Wow thanks. Linker scripts, I had no idea...

I guess the ALIGN(x) just sets the alignment for what follows?

I'll let you know how it works out as soon as I get the rest of the code to assemble.

-Brad

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

Quote:
I guess the ALIGN(x) just sets the alignment for what follows?
it returns the value of the next address x aligns with, and the '. =' assigns it to the current output location counter. If the symbol LD_PROGMEM_ALIGN is not defined, it just assigns the counter right back to itself. No symbol passed = normal progmem location. You will have to change whatever linker script gets used for your avr (avr4.x, avr5.x, etc.)

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

Or simply put the data into a named section and use --section-start to the linker to position it at the very top of code flash which (hopefully) will be well away from the end of .text (the .map file will confirm this). Say you have 256 bytes of data and a 16K AVR then just position it at 0x3F00