Analog Devices ee-69 Application Notes

Engineer To Engineer Note EE-69
Notes on using Analog Devices’ DSP’s, audio, & video components from the Computer Products Division
Phone: (800) ANALOG-D , FAX: (781) 461-3010, EMAIL: dsp.support@analog.com
Understanding and Using
Linker Description Files (LDFs)
There are a number of cases in which a programmer would like to control where a particular piece of code or data resides in a 2106x’s memory space.
For example, on the 21065L it is possible to execute from external memory, however this execution is performed at a reduced rate. In this case, the programmer will want to store and execute frequently used code internally and rarely used code externally.
Regardless of if one wishes to relocate a C-function or an assembly routine, the mechanism is the same. To map portions of code or data to specific memory segments, it is necessary to use the Linker Description File (referred to as the LDF).
This application note will explain the functionality of the LDF and demonstrate it’s features through an example. The implementation details of specific applications that require relatively complex LDF files (such as the external code-execution example previously mentioned) are beyond the scope of this document.
_____________________________
The first step towards gaining an understanding of the LDF is to first understand the makeup of the files involved in building a DSP executable.
- Source Files -
At the beginning of it all, we have the source files. These files contain code written in either C or Assembly. The first step towards producing an executable is to compile and/or assemble these sources. The assembler outputs files called “object files”. (The compiler outputs assembly files that are then fed to the assembler.) VisualDSP produces object files that have the extension .DOJ.
(Note: these object files are typically output to the
~/YourProject/debug directory.)
- Object Files -
The object files produced by the compiler and assembler are divided up into various “sections” or “segments” (referred to as Object Segments). Each of these Object Segments is used to hold a particular type of compiled source code. For example, such an Object Segment may hold program op-codes (48-bits wide) or data such as variables (16, 32 or 40-bits wide). Some of these Object Segments also hold information not pertinent to this discussion (since the information isn’t important to the user - such as debug-information, etc.).
Each of these different Object Segments has a different name that is specified in the source code. Depending on whether the source is C or assembly, there is a different convention for specifying this Object Segment Name.
In an assembly source, the code and/or data is placed between the “.segment SegName” and the “.endseg” statements will then be found in the Object Segment called “SegName”. Here is an example:
.segment /dm asmdata
.var foo[3];
.endseg
.segment /pm asmcode
r0 = 0x1234; r1 = 0x4567; r2 = r1 + r2;
.endsegment
Here, the Object Segmentasmdata” would contain the array foo, and the 3-lines of code would be located in the Object Segmentasmcode”.
In a C source the programmer would use the
segment(“seg_name”) directive. Here is an
example:
segment(“ext_data”) int temp;
a
segment("extern") void func1(void) {
int x = 1;
}
void func2(void) {
int i = 0;
}
When this C-file is compiled, the code generated from
func1 will be stored in its own separate Object
Segment of the of the .DOJ file named “extern”. The
variable “temp” will reside seperately in the “ext_data”.
So what happens to func2? If an Object segment Name isn’t specified, the compiler will use a set of default names. So in this case, the object file would hold the code from func2 in an Object Segment for program code which happens to have a default Object Segment Name of “seg_pmco”.
Page 2-60 of the “C Compiler Guide & Reference for the ADSP-2106x
Family DSPs” lists the default Object Segment Names.
(Note: there are no default Object Segment Names for assembly source files, and the .segment/ .endseg statements MUST be used.)
How these Object Segments and Object Segment Names relate to code placement in memory will be illustrated later.
- Executable Files -
Once all of the source files have been assembled and/or compiled into their respective object files, it is then the job of the linker to combine all of these object files into one integrated executable which has the extension .DXE.
Just like the object file, the executable is broken up into different “segments”. (As dictated by the ELF
[Executable and Linking Format] file standard that’s conformed to by the .DXEs produced by Visual DSP.) These segments
are referred to as DXE Segments, and as you may suspect, the segments have DXE Segment Names.
It is absolutely crucial to understand that these DXE Segment Names are completely independent of the Object Segment Names. They exist in different name-spaces, which means that you can actually have a DXE Segment Name that is exactly the same as an Object Segment Name. (Unfortunately, in most distributed examples, this is the case. This use of the same name for different items, although legal, is poor programming style and makes for a confusing LDF).
It is also important to understand the function of the .DXE. The .DXE is not what is loaded into the DSP, and it is not what is burned into an EPROM. This is because the DXE contains “extra” information (in addition to the raw code and data from the object files.) This data is used by “down stream tools” such as the Loader (used to create an EPROM) and the Debugger (used for simulation/emulation), to properly locate code in the DSP.
So How Does the LDF Relate to All of These
Different Files?
The linker’s job in all of this is reasonably straightforward. Based on commands in the LDF file, the linker takes all of the Object Segments from all the object files, and using the memory model declared in the LDF file, combines them all into a single executable .DXE file.
So let’s look at an example LDF file to understand how this process works! We will examine an LDF that’s used to link assembly-only source code. This is the simplest type of LDF because C-source code needs to be supported in the LDF with additional information about the C-run-time-header and other such library information.
The remainder of this application-note will discuss Code Listing 1 - test.ldf. Each numbered section below describes a feature in the LDF file. The section number corresponds to a number in the LDF file that we’ve added (using the [#:] format) beside the LDF feature in question.
1) The first thing of interest in the LDF is the Memory{} command. This defines the memory model. It tells the linker what Memory Spaces are available and gives them names called Memory Space
EE-69 Page 2 Notes on using Analog Devices’ DSP, audio, & video components from the Computer Products Division
Phone: (800) ANALOG-D or (617) 461-3881, FAX: (617) 461-3010, EMAIL: dsp.support@analog.com
Loading...
+ 2 hidden pages