a
a
aa
Phone: (800) ANALOG-D, FAX: (781) 461-3010, EMAIL: dsp.support@analog.com, FTP: ftp.analog.com, WEB: www.analog.com/dsp
Placing C Code and Data Modules
in SHARC memory using
VisualDSP++ ™
Introduction
When developing C code for a DSP application, you
often need to explicitly place code and data at
specific addresses in memory.
This EE Note presents two techniques to do this.
The first technique involves editing the LDF files to
explicitly locate entire object files in memory
segments. The second technique shows how to use
the SECTION keyword in your C source code to
explicitly place individual variables and functions in
specific memory segments.
In the pre-VisualDSP releases of the SHARC Tools
(Release 3.3) you could easily place C code in an
alternate memory segment defined in the
architecture file by using the -mpmcode compiler
switch. This switch allowed you to specify which
architecture file segment contained that specific
code or data object file. An example command line
using this switch is shown below:
g21k filename.c -mpmcode=alt_pmco -a alt.ach
In VisualDSP++ the -mpmcode switch is no longer
valid. Instead, users can use one of the methods
described below to achieve the same results.
The job of the C compiler is to translate the user's C
code into assembly code. In doing this, the
compiler needs to place code and data in memory
segments that are defined in the LDF file. The
compiler uses a predetermined set of memory
segments to place code and data modules. The
default LDF file that comes with the VisualDSP++
Engineer To Engineer Note EE-132
Technical Notes on using Analog Devices’ DSP components and development tools
tools use these memory segments which are listed
and described below:
seg_pmco Default segment name for
code storage.
seg_dmda Default segment name for
data memory global variables
and static variables.
seg_pmda Default segment name for
program memory data
variables.
seg_rth Segment name for system
initialization code storage
and Runtime Header.
seg_init Segment name for Runtime
Initialization storage.
Because the compiler uses these segment names
during compilation, the LDF file must be edited
in order to place code or data in other memory
segments. These changes are made to the
MEMORY and SECTIONs portion of the LDF file.
The example below shows how to manipulate your
LDF file to change the placement of your code.
Code Example
Consider the following 2 code modules:
/* main.c */
extern int sum(int a,int b);
int ext_a=0xa,int ext_b=0xb;
void main(void)
{
int i=5;
int j=3;
int total;
Copyright 2001, Analog Devices, Inc. All rights reserved. Analog Devices assumes no responsibility for customer product design or the use or application of customers’ products or for any
infringements of patents or rights of others which may result from Analog Devices assistance. All trademarks and logos are property of their respective holders. Information furnished by Analog
Devices Applications and Development Tools Engineers is believed to be accurate and reliable, however no responsibility is assumed by Analog Devices regarding the technical accuracy of the
content provided in all Analog Devices’ Engineer-to-Engineer Notes.
i = sum(i,j);
total=ext_a+ext_b;
idle();
}
/* ext.c */
int sum(int a, int b)
{
return a+b;
}
Main.c is a code module that will call the function
sum from the file named ext.c. If we were to
compile this code with any of the default LDF files,
all of the code modules would be placed in
seg_pmco, and all of the data variables would be
placed in seg_dmda.
Our goal is to place the external function sum in a
code segment a called alt_pmco, and to place the
two variables, ext_a and ext_b in a code segment
called mem_dmda. There are two ways to do this:
Modify the LDF files, or use the SECTION
keyword in the C source code. We will show
examples of both methods.
Option #1 – Modifying the LDF File
We’ll use this method to change the linker’s
placement of the object file ext.doj.
First, we will add two new segments to the
MEMORY section of the LDF file. The two
memory segments are named alt_pmco (for code
storage) and mem_dmda (for 16-bit data storage –
this will be used later).
MEMORY
{
seg_rth { TYPE(PM RAM) START(0x00020000)
END(0x000200ff) WIDTH(48) }
seg_init { TYPE(PM RAM) START(0x00020100)
END(0x000217ff) WIDTH(48) }
seg_pmco { TYPE(PM RAM) START(0x00021800)
END(0x00025fff) WIDTH(48) }
alt_pmco { TYPE(PM RAM) START(0x00030000)
END(0x00033fff) WIDTH(48) }
seg_dmda { TYPE(DM RAM) START(0x00036000)
END(0x00037fff) WIDTH(32) }
seg_heap { TYPE(DM RAM) START(0x00038000)
END(0x00039fff) WIDTH(32) }
seg_stak { TYPE(DM RAM) START(0x0003a000)
END(0x0003dfff) WIDTH(32) }
mem_dmda { TYPE(DM RAM) START(0x0007c000)
END(0x0007ffff) WIDTH(16) }
Next, we make a small modification in the
SECTIONS portion of the LDF file. This change
will allow us to place the object file created by the
compiler from the file ext.c (called ext.doj) in the
alternate memory segment alt_pmco that we just
created. Keep in mind that we still want the main
code module to reside in seg_pmco. The boldfaced
text shows the changes to the LDF.
PROCESSOR p0
{
LINK_AGAINST( $COMMAND_LINE_LINK_AGAINST)
OUTPUT( $COMMAND_LINE_OUTPUT_FILE)
SECTIONS
{
dxe_seg_rth
{
INPUT_SECTIONS( $OBJECTS(seg_rth)
$LIBRARIES(seg_rth))
} > seg_rth
dxe_seg_init
{
INPUT_SECTIONS( $OBJECTS(seg_init)
$LIBRARIES(seg_init))
} > seg_init
dxe_seg_pmco
{
INPUT_SECTIONS( main.doj(seg_pmco)
$LIBRARIES(seg_pmco))
} > seg_pmco
dxe_alt_pmco
{
INPUT_SECTIONS( ext.doj(seg_pmco))
} > alt_pmco
dxe_alt_dmda
EE-132 Page 2
Technical Notes on using Analog Devices’ DSP components and development tools
Phone: (800) ANALOG-D, FAX: (781)461-3010, EMAIL: dsp.support@analog.com, FTP: ftp.analog.com, WEB: www.analog.com/dsp