specifying a memory location for global variable

Hi everyone,

is there a way to specify either in assembler or C where a global variable should be located in the memory? (it's an ADSP21020).

The reason for this is that, in the system I'm using, the protected area of the flash contains the runtime header which reference to a symbol called ___lib_int_table (where the address for interrupt service routines will be placed). This symbol was put by the linker at the beginning of the data memory at the time the program was built, but now that I am building a new program, which has to use the same runtime header, the only way to have the ___lib_int_table located in the same position is to follow a specific order during the linking phase, otherwise everything is screwed up.

Since I don't want to rely on this particularly fragile approach I wanted to nail down the location once forever, since is not going to change.

I know that there are C language extension for the g21k compiler which may specify whether we want to have a variable in the data memory or the program memory, but I have not found any reference for locating a global variable in a fixed memory location.

Any suggestion is appreciated.

Al

--
A: Because it fouls the order in which people normally read text.
Q: Why is top-posting such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Reply to
alb
Loading thread data ...

Does your linker take command files (e.g. foobar.ld)? If so, then you can put the thing into a segment of its own, and locate that segment where you want it. Or you can explicitly define the location in an assembly file (just define the symbol and make it global), then tell the linker that it's memory _really_ starts just above that variable.

--
Tim Wescott
Control system and signal processing consulting
www.wescottdesign.com
Reply to
Tim Wescott

Would a construct like this work? #define FIO0DIR (*(volatile unsigned long *)0x3FFFC000)

It's often used to define registers that are in specific memory locations where you'd want to be able to, for example, make an assignment, like FIO0DIR = 0xDEADBEEF;

However, you're probably best to modify the assembly-language run-time stub (e.g., crt.s or similar) and do as Tim suggests to define a specific section for the interrupt table.

--
Rich Webb     Norfolk, VA
Reply to
Rich Webb

The problem with your method is that it doesn't prevent the linker from assigning some _other_ variable to that location, unless you tell the linker to stay away from that part of memory.

Someone, either in a private mail or on this group, has mentioned that the tool set for that chip is a modified gcc chain. If that's so, then it uses ld, and ld uses linker files with a fairly well documented syntax, and part of that syntax is the ability to arbitrarily assign addresses to symbols and to arbitrarily locate segments.

Here's a snippet from one of my linker scripts:

SEARCH_DIR("/home/tim/arm-none-eabi/arm-none-eabi/thumb/lib");

/* Symbols */

GPIOA = 0x40004000; GPIOB = 0x40005000;

/* etc. */

NVIC = 0xE000E000; _stack = 0x20002000;

MEMORY { FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 64K /* */ /* FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 128K /* */ SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 8K }

SECTIONS { .vectors : { } > FLASH .text : { KEEP(*(._vector_table)) *(.vectors) *(.text* .text.* .gnu.linkonce.t.*) *(.plt) *(.gnu.warning) *(.rodata* .rodata.* .gnu.linkonce.r.*)

/* etc. some more

}

In this case, the OP could either use a compiler directive to put ___lib_int_table into a special segment, then locate that segment at the start of data memory (similar to the way the .vectors segment is explicitly located before .text in the above linker command script), or the OP could put a statement in there like

___lib_int_table = ;

and start memory at the next word after ___lib_int_table. I'd do the special segment razz-matazz: it takes the size of ___lib_int_table into account, makes sure things are properly aligned, and even if it means depending on some non-portable features of the compiler, by the time you get that close to the hardware your C is getting pretty tool-dependent anyway.

--
My liberal friends think I'm a conservative kook.
My conservative friends think I'm a liberal kook.
Why am I not happy that they have found common ground?

Tim Wescott, Communications, Control, Circuits & Software
http://www.wescottdesign.com
Reply to
Tim Wescott

Indeed. And yes, this does look cleaner (and more reliable).

--
Rich Webb     Norfolk, VA
Reply to
Rich Webb

On 3/13/2012 5:08 PM, Tim Wescott wrote: [...]

the tool set is a port from gcc but the linker (ld21k) doesn't seem to get anything as additional input except the 'architecture file' which it does not seem to me to allow the freedom your script is showing.

[...]

It does not seem to me the architecture file syntax will allow this type of statements. The additional problem here is that ___lib_int_table is a global variable defined in the library as follows:

!file int_tabl.asm #include "lib_glob.h" #include "sig_glob.h"

.SEGMENT/RAM_SPACE Ram_Space_Name;

.GLOBAL ___lib_int_table; .VAR ___lib_int_table[___SIG_LAST_INTERRUPT * siga_size];

.ENDSEG

Now the 'RAM_SPACE' is not understood by the linker at all, but when the library is compiled all the GLOBAL and VAR go in a segment called seg_dmda by default.

When I link against this object I don't have a way to specify through the architecture file where it should go in the memory unless the object is first in the list of objects and then is automatically located at the beginning of the memory.

On top of this, if I declare some static or global variable in my main.c file, then they will go first unless I first create the main.o and then call the linker separately to link the objects together.

I can certainly avoid to declare static or global variables in my main.c (this is probably a good practice anyway), but was a headache before I realized what the hack the processor was doing.

Reply to
alb

On 3/14/2012 9:37 AM, alb wrote: [...]

Ok RAM_SPACE is a #define for DM, while Ram_Space_Name is a define for seg_dmda. I think the author thought RAM_SPACE would have been more readable than DM... what a genius!

Reply to
alb

I think you might be giving up too soon -- see if you can figure out how to give that vector it's own segment name, and diddle with your architecture file to see if you can put that segment where you want it.

I would be _very_ surprised if there wasn't some way to achieve this.

--
My liberal friends think I'm a conservative kook.
My conservative friends think I'm a liberal kook.
Why am I not happy that they have found common ground?

Tim Wescott, Communications, Control, Circuits & Software
http://www.wescottdesign.com
Reply to
Tim Wescott

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.