 C COMPILER
Since the TMS320C32 has internally a 32 bit
architecture, the C Compilers data types remain 32
bits. However, the C Compilers Run Time Support
Library include pragma directives and new dynamic
allocation routines (malloc, realloc, calloc, bmalloc,
free, etc.) that support the creation of data sections
that serve as memory pools (or heaps) to store 16 and 8
bit data size values. Note that these sections can reside
in 8, 16, or 32 bit wide memory. The programmer must make
sure that the appropriate Strobe Control Register is
loaded with the correct data size and memory width.
According to the settings of the Strobe Control register,
the TMS320C32 memory interface will truncate, pack, or
unpack the data appropriately. The following table
illustrates the data sizes supported by the different
sections (blocks of code or data) created by the C
Compiler.
| Section Type
|
Data Size |
| 32-bit |
16-bit |
8-bit |
Initialized
|
.text
.cinit
.const
.user_section
|
.user_section
|
.user_section
|
Uninitialized
|
.bss
.stack
.sysmem
.user_section
|
.sysm16
.user_section
|
.sysm8
.user_section
|
These sections contain:
The following sections describes the preprocessor
pragma and two files added to the Run Time Support
Library that support these 8 bit and 16 bit memory pools.
Note that 32 bit memory pools are handled through the
standard minit(), malloc(), calloc(),
realloc(), and free() routines that
operate on the .sysmem section.
DATA_SECTION Pragma
Directive
To support additional memory pools, the C Compiler
utilizes a data section pragma directive. This pragma
directive instructs the C Compiler to allocate space for symbol_name
in the section specified by section_name of size symbol_size.
Its syntax is as follows:
For example, to define a new section called
.mydata as an array of 1024 integer values
use:
MEMORY8.C
The MEMORY8.C module contains functions that implement
dynamic memory management routines for the
TMS320C32s 8 bit data sizes. It consist of the
following: pragma directive that defines a .sysm8
section. The size of this memory pool in words (system
memory or heap) is set at link time by using the -heap8
option. If the -heap8 option is not used, the
compiler does not allocate 8 bit system memory area. If
no arguments is given to this switch, the size of the 8
bit system memory area defaults to 1024, 8 bit words.
- minit8() function that initializes
and resets the 8 bit dynamic memory management
system. This function is analogous to the minit()
function, except that operates in the 8 bit
.sysm8 section.
- malloc8() function that allocates 8
bit words from the 8 bit memory pool and returns
a pointer to the allocated space. This function
is analogous to the malloc() function,
except that operates in the 8 bit .sysm8
section.
- calloc8() function that allocates 8
bit words from the 8 bit memory pool, clears
these locations, and returns a pointer to the
allocated space. This function is analogous to
the calloc() function, except that
operates in the 8 bit .sysm8
section.
- realloc8() function that
reallocates a different space of 8 bit words from
previously allocated space in the 8 bit memory
pool and returns a pointer to the allocated
space. This function is analogous to the realloc()
function, except that operates in the 8 bit
.sysm8 section.
- free8() function that frees
previously allocated space from the 8 bit memory
pool. This function is analogous to the free()
function, except that operates in the 8 bit
.sysm8 section.
- bmalloc8() function that allocates
8 bit words from the 8 bit memory pool aligned to
a boundary suitable for the TMS320C32Õs circular
and bit-reversed buffers and returns a pointer to
the allocated space. This function is analogous
to the bmalloc() function, except that
operates in the 8 bit .sysm8
section.
- _SYSMEM8_SIZE is an external label
that holds the size in words of the 8 bit system
memory pool.
MEMORY16.C
The MEMORY16.C module contains functions that
implement dynamic memory management routines for the
TMS320C32s 16 bit data sizes. It consists of the
following:
- pragma directive that defines a Ò.sysm16
section. The size of this memory pool in words
(system memory or heap) is set at link time by
using the -heap16 option. If the
&endashheap16 option is not used, the
compiler does not allocate 16 bit system memory
area. If no arguments is given to his switch, the
size of the 16 bit system memory area defaults to
1024, 16 bit words.
- minit16() function that initializes
and resets the 16 bit dynamic memory management
system. This function is analogous to the minit()
function, except that operates in the 16 bit
.sysm16 section.
- malloc16() function that allocates
16 bit words from the 16 bit memory pool and
returns a pointer to the allocated space. This
function is analogous to the malloc()
function, except that operates in the 16 bit
.sysm16 section.
- calloc16() function that allocates
16 bit words from the 16 bit memory pool, clears
these locations, and returns a pointer to the
allocated space. This function is analogous to
the calloc() function, except that
operates in the 16 bit .sysm16
section.
- realloc16() function that
reallocates a different space of 16 bit words
from previously allocated space in the 16 bit
memory pool and returns a pointer to the
allocated space. This function is analogous to
the realloc() function, except that
operates in the 16 bit .sysm16
section.
- free16() function that frees
previously allocated space from the 16 bit memory
pool. This function is analogous to the free()
function, except that operates in the 16 bit
.sysm16 section.
- bmalloc16() function that allocates
16 bit words from the 16 bit memory pool aligned
to a boundary suitable for the TMS320C32Õs
circular and bit-reversed buffers and returns a
pointer to the allocated space. This function is
analogous to the bmalloc() function,
except that operates in the 16 bit .sysm16
section.
- _SYSMEM16_SIZE is an external label
that holds the size in words of the 16 bit system
memory pool.
Caution
The TMS320C32 has only three
strobes: STRB0, STRB1, and IOSTRB. Therefore, the
programmer cannot have more than three memory pools, one
memory pool assigned to each strobe. Note that IOSTRB can
only hold 32 bit data and can only accommodate the 32 bit
memory pool: .sysmem. On the other hand, STRB0 and STRB1
can hold 8/16/32 bit data and can accommodate the 8, 16,
or 32 bit memory pools: .sysm8, .sysm16, and .sysmem.
All pointers and constants must
be stored in memory configured to hold 32 bit data.
Hence, .bss, .stack, .cinit, and .const
sections must reside in memory configured to 32 bit data
size.
LINKER
To support the TMS320C32Õs 8 and 16 bit memory pools,
the linker utilizes the following switches: &endashheap8,
&endashheap16, and &endashheap that
set the size in words of the respective 8, 16, and 32 bit
memory system areas (.sysm8, .sysm16, and
.sysmem). The user must link these sections into the
appropriate addresses, activating strobes that will be
configured to access either 8, 16, or 32 bit data sizes.
For example, to specify the size of 8 bit memory pool
at link time to 256K words, use:
The linker creates these memory system areas only if
there exists the respective .sysmem, .sysm8,
and .sysm16 sections in an input file.
The linker also creates the global symbols
_SYSMEM_SIZE, _SYSMEM8_SIZE, and _SYSMEM16_SIZE and
assigns it a value equal to the size of the respective heap,
heap8, and heap16. The default size for
each memory system area is 1K words.
DEBUGGER
For the debugger to properly disassemble and
read/write external memory, the user must configure the
Strobe Control Registers before loading and executing his
code. Since the TMS320C32 supports code execution from 16
or 32 bit memory, the debugger might need to temporarily
set the Strobe Control Register to 32 bit data size in
order to write an instruction (either by loading code or
patching code) or read an instruction in order to
disassemble a range of program memory. To support this,
the Memory Map Add command includes a new type
parameter that directs the debugger to treat .text
sections as 32 bit data. While reading or writing .text
sections, the debugger temporarily stores the
configuration of the appropriate Strobe Control Register,
temporarily sets the data size to 32 bits, reads or
writes the portion of the Ò.textÓ section, and restores
the Strobe Control Register to its previous value. The
syntax for the Memory Map Add Command is as follows:
EXAMPLES
Two External Memory Banks
TMS320C32s external memory interface allows the
use of two zero wait state external memory banks with
different widths without incurring in any access penalty
and additional logic. This allows the programmer the
flexibility in trading off performance versus system cost
(amount of memory chips). For instance, the programmer
could execute code from 32 bit wide memory while storing
data in 8-bit memory, as shown in Figure 6. This would be
an advantage to applications with large amounts of 8 bit
data that require execution at the fastest speed of the
device.
Figure 6: Zero Wait State Interface
for 32-bit and 8-bit SRAM Banks
In this example, a bank of 32K by 3- bit is mapped to
STRB0 while a bank of 32K by 8-bit is mapped to STRB1.
For this configuration, the programmer must set the STRB0
Control Register Physical Memory Width to 32-bits, Data
Type Size to 32-bits, and the STRB Config bit field to
zero since the banks are separate memories (STRB0 Control
Register = 000F0000h). Also, the programmer must set the
STRB1 Control Register Physical Memory Width to 8-bits
and the Data Type Size to 8-bits (STRB1 Control Register
= 00000000h).
This example maps the external memory address pins of
the 32-bit wide bank, A14A13...A1A0, to the
TMS320C32s A14A13A12...A1A0. On the other hand, the
8-bit wide bank memory address pins, A14A13...A1A0, are
mapped to the TMS320C32s A21A13A12...A1A0A-1. Note
that since STRB1 is configured for 8-bit memory width,
the external address presented on TMS320C32 s pins
is shifted right by two bits. With this mapping, external
memory accesses in the range 0h through 7FFFh read/write
32-bit data to the 32-bit wide bank (STRB0) while memory
accesses in the range 900000h through 907FFFh read/write
8-bit data to the 8-bit wide bank (STRB1).
Note that two banks of different memory widths should
not be connected to the same STRB without external decode
logic. Different memory widths require signals to be
configured as address pins. These address pins are active
for any external memory access (STRB0, STRB1, IOSTRB, and
program fetches).
C Code - Dynamic Memory
Allocation
The following C Code illustrates the allocation of two
buffers (1K and 4K, 8-bit words) using the 8-bit dynamic
memory allocation routines:
void
main()
{
int *buffer1;
float *buffer2;
/* STRB0 Control Register configured to 32 bit wide
memory and 32 bit data size */
*0x808064 = 0xF0000;
/* STRB1 Control Register configured to 8 bit wide memory
and 8 bit data size */
*0x808068 = 0x00000;
buffer1 = malloc8( 1024 * sizeof(int) ); /* allocate 1K 8
bit words in the 8 bit memory pool */
buffer2 = malloc8( 4096 * sizeof(float) ); /* allocate 4K
8 bit floats in the 8 bit memory pool */
callDSPoperation( buffer1, buffer2); /* process buffers
*/
free8( buffer2 ); /* free buffers */
free8( buffer1 );
}
Note that the TMS320
Floating Point C Compiler sizeof function returns 1 for
both integers and floats data types.
Linker Command File -
Dynamic Memory Allocation
The following linker command file allocates the
sections of the code into the desired memory
configuration:
sample.obj
/* Input filename */
heap8 32768 /* Set 8 bit memory pool size */
stack 8704 /* Set C system stack size */
o sample.out /* Specify output file */
m sample.map /* Specify map file */
MEMORY
{
PRGRAM : org = 0x0000, len = 0x2000
STRB0RAM : org = 0x2000, len = 0x6000
ONCHIRAM : org = 0x87Fe00, len = 0x200
STRB1RAM : org = 0x900000, len = 0x8000
}
SECTIONS
{
.text > PRGRAM /* 32 bit data section */
.cinit > STRB0RAM /* 32 bit data section */
.const > STRB0RAM /* 32 bit data section */
.bss > STRB0RAM /* 32 bit data section */
.stack > STRB0RAM /* 32 bit data section */
.sysm8 > STRB1RAM /* 8 bit memory pool mapped to STRB1
*/
}
Debugger Batch File
The following debugger batch file executes
initialization commands to configure the C Source
Debugger to handle a TMS320C32 device in the memory
configuration of Figure 6. Note that STRB0 and STRB1
Control Registers must be initialized prior to code
download.
mr
sconfig init.clr
; Define memory configuration
ma 0x0000, 0x2000, R|W|TX ; Inform debugger that this
section holds code (.text )
ma 0x2000, 0x6000, RAM ; No code here, STRB0
ma 0x87FE00, 0x200, RAM ; On-chip
ma 0x808000,0x10,RAM ; Peripheral Bus Control - DMA
ma 0x808020,0x20,RAM ; Peripheral Bus Control - Timers
ma 0x808040,0x10 ,RAM ; Peripheral Bus Control - Serial
Port 0
ma 0x808060,0x10,RAM ; Peripheral Bus Control - External
Memory Interface
ma 0x900000, 0x8000, RAM ; STRB1
;
reset
map on ; Make emulator aware of this memory configuration
;
?*0x808064 = 0xF0000 ; Set STRB0 Control Register
to 32 bit memory width and 32 bit data size
?*0x808068 = 0x00000 ; Set STRB1 Control Register
to 8 bit memory width and 8 bit data size
;
load sample.out ; Need to configure STRB0 & STRB1
Control Registers before loading code
C Code - Static Memory
Allocation through User Section
The following C Code and Linker Command File
illustrate the static allocation of two buffers (1K and
4K, 8-bit words) by defining an user section called
.mydata8 that holds a structure consisting of
two arrays of data values:
#pragma
DATA_SECTION ( buffer8, .mydata8 )
struct bufferStruct {
in[1024];
out[4096];
} buffer8;
void main()
{
/* STRB0 Control Register configured to 32 bit wide
memory and 32 bit data size */
*0x808064 = 0xF0000;
/* STRB1 Control Register configured to 8 bit wide memory
and 8 bit data size */
*0x808068 = 0x00000;
callDSPoperation( buffer8.in, buffer8.out ); /* process
buffers */
}
Linker Command File -
Static Memory Allocation through User Section
The following linker command file allocates the
sections of the code into the desired memory
configuration:
sample.obj
/* Input filename */
stack 8704 /* Set C system stack size */
o sample.out /* Specify output file */
m sample.map /* Specify map file */
MEMORY
{
PRGRAM : org = 0x0000, len = 0x2000
STRB0RAM : org = 0x2000, len = 0x6000
ONCHIRAM : org = 0x87Fe00, len = 0x200
STRB1RAM : org = 0x900000, len = 0x8000
}
SECTIONS
{
.text > PRGRAM /* 32 bit data section */
.cinit > STRB0RAM /* 32 bit data section */
.const > STRB0RAM /* 32 bit data section */
.bss > STRB0RAM /* 32 bit data section */
.stack > STRB0RAM /* 32 bit data section */
.mydata8 > STRB1RAM /* 8 bit memory pool mapped to
STRB1 */
}
Single External Memory
Bank
Consider the case of a typical audio compression
application written in C language that requires a 32 bit
data for system stack and 16 bit data for the audio
buffers. In this case, the programmer might interface the
TMS320C32 as shown in Figure 7. This examples assumes a
32K of 32-bit words external memory that contains 8.5K of
32-bit words of stack and 8K of 32-bit words of program
(including constants, global, and static variables), both
mapped to STRB0. Also, the external memory contains 32K
of 16-bit words data buffers that are mapped into STRB1.
Due to this mapping, the programmer must set the STRB0
Control Register Physical Memory Width to 32 bits, Data
Type Size to 32 bits, and set the STRB Config bit field
to 1 (STRB0 Control Register = 002F0000h). It also
requires the programmer to set the STRB1 Control Register
Physical Memory Width to 32 bits and the Data Type Size
to 16 bits (STRB1 Control Register = 000D0000h).
Moreover, the PRGW pin must be pulled low to indicate 32
bit program memory width.
Figure 7: Zero-Wait State Interface
for 32 bit SRAMs with 16 and 32 bit Data Accesses
Note that the external memory address pins,
A14A13...A1A0, are mapped to the TMS320C32s
A22A13A12...A1A0. This mapping was chosen to place the
system stack following the TMS320C32s internal RAM,
thus improving performance by placing the top of the
stack in internal RAM and allowing it to grow into
external RAM. With this mapping, external memory accesses
in the range 4000h through 7FFFh will read or write 16
bit data while memory accesses in the range 0h through
3FFFh reads or writes 32 bit data. The PRGW pin controls
the program fetches.
Figure 8 shows the contents of the external memory.
Due to the address shift of the TMS320C32s external
memory interface, the memory map seen by the TMS320C32
CPU is slightly different. Figure 9 depicts this memory
map.
| |
|
0h
1FFFh |
System
Stack Area
(8K ¥ 32-bit)
|
| 2000h
|
program
word 0
|
| |
program
word 1
|
| |
.
.
.
|
| 3FFFh
|
program
word 8191
|
| 4000h
|
data1
|
data0
|
| 4001h
|
data3
|
data2
|
| |
.
.
.
|
.
.
.
|
| 7FFFh
|
data32767
|
data32766
|
Figure 8: External Memory Map
| 0h |
.
.
.
|
2000h
3FFFh |
Program
(8K ¥ 32-bit)
|
| |
.
.
.
|
87FE00h
87FFFFh |
Internal RAM
(Stack)
(512 ¥ 32-bit)
|
880000h
881FFFh |
System Stack
(8K ¥ 32-bit)
|
| |
.
.
.
|
900000h
907FFFh |
Data Buffers
(32K ¥ 16-bit)
|
FFFFFFh |
.
.
.
|
Figure 9:
TMS320C32s Memory Map
C Code - Dynamic
Allocation
To allocate dynamically 2 buffers of 1K and 4K, 16 bit
words, the user must use the 16-bit dynamic memory
allocation routines provided by the Run Time Support
Library as follows:
void
main()
{
int *buffer1;
float *buffer2;
/* STRB0 Control Register configured to STRB0 & STRB1
Overlay, 32 bit memory width,
and 32 bit data size */
/* If using the PRTS30 headers,
BUS_ADDR->strb0_gcontrol = STRB0_1_CNFG | MEMW_32 |
DATA_32; */
*0x808064 = 0x2F0000;
/* STRB1 Control Register configured to 32 bit memory
width and 16 bit data size */
/* If using the PRTS30 headers,
BUS_ADDR->strb1_gcontrol = MEMW_32 | DATA_16; */
*0x808068 = 0xD0000;
buffer1 = malloc16( 1024 * sizeof(int) ); /* allocate 1K
16 bit words in the 16 bit memory pool */
buffer2 = malloc16( 4096 * sizeof(float) );/* allocate 4K
16 bit floats in the 16 bit memory pool */
callDSPoperation( buffer1, buffer2); /* process buffers
*/
free16( buffer2 ); /* free buffers */
free16( buffer1 );
}
Linker Command File
The linker command file that allocates the sections of
the code into the desired memory configuration of Figure
8 is shown below:
sample.obj
/* Input filename */
heap16 32768 /* Set 16 bit memory pool size */
stack 8704 /* Set C system stack size */
o sample.out /* Specify output file */
m sample.map /* Specify map file */
MEMORY
{
STRB0RAM : org = 0x2000, len = 0x2000
STACKRAM : org = 0x87Fe00, len = 0x2200
STRB1RAM : org = 0x900000, len = 0x8000
}
SECTIONS
{
.text > STRB0RAM /* 32 bit data section */
.cinit > STRB0RAM /* 32 bit data section */
.const > STRB0RAM /* 32 bit data section */
.bss > STRB0RAM /* 32 bit data section */
.stack > STACKRAM /* 32 bit data section */
.sysm16 > STRB1RAM /* 16 bit memory pool mapped to
STRB1 */
}
Debugger Batch File
The following debugger batch file executes
initialization commands to configure the C Source
Debugger to handle a TMS320C32 device in the memory
configuration of Figure 8. Note that STRB0 and STRB1
Control Registers must be initialized prior to code
download.
mr
sconfig init.clr
; Define memory configuration
ma 0x2000, 0x2000, R|W|TX ; Inform debugger that this
section might hold code (.text )
ma 0x87FE00, 0x2000, RAM
ma 0x900000, 0x8000, RAM
map on ; Make emulator aware of this memory configuration
;
?*0x808064 = 0x2F0000 ; Set STRB0 Control Register to
STRB0 & STRB1 overlay,
; 32 bit memory width, and 32 bit data size
?*0x808068 = 0xD0000 ; Set STRB1 Control Register 32 bit
memory width and 16 bit data size
;
load sample.out ; Need to configure STRB0 & STRB1
Control Registers before loading code
|