Locating a library file at a fixed address

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

Hello,

 

I am developing using Atmel Studio 7 and have just completed a program that is 148K in size, which will fit nicely within the xmega256A3BU. About 80% of the code contains only small clips of musical songs (~480 music clips) stored within program memory that will never change.

 

The other portion of program code contains code which will be changing over time and therefore I have a bootloader for customer updates.

 

I would like to separate the two sections in flash so the update process is not having to transfer the fixed code data (~56K) that never changes with each update.

 

I am asking for suggestions on how to accomplish this.

 

I have tried placing all of the music clips into a library but I do not know how to offset a library file to a higher memory location. Or am I going about this wrong?

 

Thank you,

Al

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

I assume you are talking about avr-gcc here?

 

If so the tool that is responsible for locating things is the linker. There are two ways to instruct it where to locate something specific and both of them start by putting the "object" (code or data) into a named section in the program so if you currently have something like:

uint8_t sound_data[] = { 0x37, 0xF4, 0xB5, 0xC2, 0x89, 0x98, 0xAE ... };

then you start by switching that to be:

__attribute__((sections(".sound1"))) uint8_t sound_data[] = { 0x37, 0xF4, 0xB5, 0xC2, 0x89, 0x98, 0xAE ... };

Now, when that item is compiled it won't just go to default memory sections (.text, .data, .bss, .progmem, etc) but will be put into its own memory section called .sound1.

 

Later you need tell the linker where you would like everything in .sound1 to be located in memory. One way is a command line parameter to the linker:

-Wl,-section-start=.sound1=0xB800

That tells it to place everything in .sound1 from 0xB800 onwards. However using this technique it's possible you may "bump into" something the linker is already placing. For all you know perhaps there is already some part of .text at 0xB800. If there is the linker will warn you but if you want it to place this stuff so it definitely does not clash then you might consider modifying the default "linker script" which is a "recipe" for how things will be laid out in memory. You could add some section "inbetween" other sections if you liked.

 

But the easy option is to pick some area at the "top of flash" (well unless there's a bootloader) and just pick a fixed base address there that all the sound data will live at.

Unless you want to put each sound in a separate area I would just assign them all to one location. Because the __attribute__ thing is long winded typing then you might:

#define SOUNDS __attribute__((section(".sound")))

SOUNDS uint8_t sound1[] = { ... };
SOUNDS uint8_t sound2[] = { ... };
etc.

then just use a -section-start for the base of ".sound"

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

Hi Clawson,

 

What an excellent and thorough explanation you have put forth. Thank you much for your time.

 

Unfortunately, I have two follow-on questions.

 

  1. I revised my application with it's start at 0x00000 and the music clips up at 0x20000 using your above explanation. A review of the map file does verify all the clips are located into the desired ".sound" section. However since the plan is to have the application section capable of  field updates, all of the music clips addresses would be broken after an update.

    I though about placing a lookup table at the beginning of the ".sound" section to solve the issue. This gateway function would receive the music clip number as a parameter input, and by using the lookup table, return a pointer to the assigned music clip address.

    Is it possible (with Atmel Studio 7) to place this new lookup table at the beginning of the .sound section and insure it always ends up at the beginning of the .sound section?
     

  2. How would I make a call from the app section to the new lookup table located at 0x20000 in the ".sound" section. Passing in a parameter  (as sound clip id) and getting a pointer returned pointing to the desired music clip address? Sorry, I am use-to 64K chips.
     

Again, thanks for your very helpful expert suggestions and answers.
Al

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

BocaDev wrote:
I though about placing a lookup table at the beginning of the ".sound" section to solve the issue.
Seems like a good plan but note that pointers in AVR are 16 bit wide yet you are talking about locations that are wider than that so from avr/pgmspace.h you will need to use pgm_get_far_address():

 

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

 

and I am not sure how you can build a table of "Pointers" at compile time to have such 32 bit entries?

BocaDev wrote:
How would I make a call from the app section to the new lookup table located at 0x20000 in the ".sound" section.
Wellat run time you would definitely use that pgm_get_far_address(). So something like:

farptr_t pSound2;

pSound2 = pgm_get_far_address(&sound2[0]);

for(int i = 0; i < 1000; i++, pSound2++) {
    play(pgm_read_byte_far(pSound2));
}

But that, of course, relies on sound2[0] being at a fixed address.

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

clawson wrote:
and I am not sure how you can build a table of "Pointers" at compile time to have such 32 bit entries?
I would try it with __memx instead. That should also eliminate the need for the pgm_read_XXX_far functions.

Stefan Ernst

Last Edited: Wed. Jul 19, 2017 - 08:34 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh good point!

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

Thanks guys, great stuff!

 

Lots of good guidance with ideas I will be looking into.

 

BocaDev