#Introduction
This page describes the compiler section names and how to link them in your project.
This article has been written with the C28x flash device in mind.
#Other Resources
* [TMS320C28x Optimizing C/C++ Compiler User's Guide (spru514)](https://www.ti.com/lit/pdf/spru514)
* [TMS320C28x Assembly Language Tools User's Guide (spru513)](https://www.ti.com/lit/pdf/spru513)
The following application note describes in detail how to link code when running
in RAM or Flash. It also includes information on including DSP/BIOS.
* [Running an Application from Internal Flash Memory on the TMS320F28xx DSP (spra958)](https://www.ti.com/lit/an/spra958l/spra958l.pdf)
* [Associated code](https://www.ti.com/lit/zip/spra958)
The following is great general Code Generation Tools Information. Much of it applies to C28x:
* [Compiler Wiki Area](https://processors.wiki.ti.com/index.php/Compiler)
* [Code Gen Tools Tips and Tricks for Beginners Wiki Article](https://processors.wiki.ti.com/index.php/CGT_Tips_%26_Tricks_for_Beginners)
* [Code Generation Tools FAQ Wiki Article](https://processors.wiki.ti.com/index.php/Code_Generation_Tools_FAQ)
#Understanding Compiler Sections
Every C program consists of different parts called sections. All default sections
begin with a leading dot (.text, .ebss, etc). The compiler has section names for
initalized as well as unitialized variables. The section names that will be generated
by the following code are indicated in the comments:
```c
//
// Global variables x & y ==> .ebss
// Initial values 2 & 7 ==> .cinit
//
int x = 2;
int y = 7;
void main()
{
long z; // Local variable => .stack
z = x + y; // Code => .text
}
```
The Compiler sections are documented in the
[TMS320C28x Optimizing C/C++ Compiler User's Guide (spru514)](https://www.ti.com/lit/pdf/spru514).
##Types of Compiler Sections
During development both initalized sections and uninitalized sections should be
linked to SARAM. This makes debug faster since the flash will not need to be
erased and programmed after each minor change.
Once the initial debug is complete and the code works, initialized sections can
be moved to FLASH. Once this is done the code should be tested again.
Section Name | Description | Section Type | Link Location
-------------|----------------------------------------|----------------|--------------
.text | Executable code and constants | Initalized | Load into non-volatile memory (flash). Run time-critical code in SARAM. See Note.
.cinit | Initalized global and static variables | Initalized | Non volatile memory (flash)
.econst | Constant data (e.g. const int k = 3;) | Initalized | Non volatile memory (flash)
.switch | Tables for switch statements | Initalized | Non volatile memory (flash)
.ebss | Global and static variables | Uninitalized | Volatile memory (SRAM)
.stack | Stack space | Uninitalized | Volatile memory (SRAM). The C28x Stack Pointer (SP) is 16 bits. .stack must be in the low 64k words.
.esysmem | Memory for malloc type functions | Uninitalized | Volatile memory (SRAM)
.reset | Reset vector | Initalized | This section is not typically used by C28x devices and should be set to type=DSECT.
[[y Notes:
Time-critical code will typically be linked with a load address in flash, and a run address in SARAM.
The application will then copy it from flash to SARAM.
]]
##The .reset section
The compiler generates a section called .reset that holds nothing more than the
address of the _c_init00 routine (the c-initilization routine). The purpose of
this section is to provide a reset vector. For most 28x devices, however, the
reset vector will be in the boot ROM of the device. For this reason, the .reset
section can be set to "TYPE = DSECT" in the linker command file as described
later in this article.
The exception to this rule is a 281x device with external interface. On this
device zone 7 can be mapped such that the reset vector is in external memory.
In this case the .reset section might be useful.
#Controlling the Linking Process
The linking step uses the memory description from the linker command file (.cmd).
This file tells the linker how to place the software into the hardware. The
format of the linker command file is described in the
[TMS320C28x Assembly Language Tools User's Guide (spru513)](https://www.ti.com/lit/pdf/spru513).
It's suggested that you start with a linker file from a working example and then
modify it for your needs. The linker command file has two basic parts.
##Memory Map Description
This part of the .cmd file tells the linker what memory blocks are available.
* Memory block name
* The memory block location
* Size of the memory block
An example of the memory map description is shown below:
```c
/* Memory Map Description
Describe the memory blocks on the device */
MEMORY
{
PAGE 0: /* Program Space */
H0SARAM: org = 0x00A000, len = 0x2000
PAGE 1: /* Data Space */
M0SARAM: org = 0x000000, len = 0x400
M1SARAM: org = 0x000400, len = 0x400
L0SARAM: org = 0x008000, len = 0x1000
L1SARAM: org = 0x009000, len = 0x1000
}
```
###PAGE 0 or PAGE 1
PAGE 0 is typically used for program sections. For example .text or other named
sections that contain code.
PAGE 1 is used for data sections. For example .stack.
In some legacy Flash programming tools, such as SDFlash, only sections on "PAGE 0"
would be programmed into the flash. Consider the .const section which is data.
If .const was allocated to PAGE 1, the SDFlash flash programmer will ignore it
and not program the data into flash. Since this is initialized data that is
constant you really want it programmed into flash. In some of our examples you
will find .const allocated to PAGE 0 for this reason. Memory blocks on C28x are
unified so it does not cause an issue.
###A Note About Unified Memory
Memory blocks on 28x devices are typically unified. That means they can be
accessed both in program space and data space. Refer to the data manual for your
device. There will be a memory map that shows the physical memory blocks and
where they are defined - program, data or both.
In the MEMORY description, these unified blocks can be placed either in page 0
(i.e. program) or page 1 (i.e. data). It is also possible to split a physical
memory block so part of the block is used by page 0 and another part used by page 1.
###Important Notes When Defining the MEMORY Section
* If code accesses data within the same physical memory, then performance will
degrade due to resource conflicts. It is better to place code and the data it
accesses separate blocks.
* Take care to not define the same memory address range in both program and data
space! Doing so may cause your data to corrupt program or vice versa.
* Wait states will degrade performance. Most SARAM is zero-wait on 28x devices.
There are some blocks, however, that are not on 2833x devices. Always check the
data manual to find the wait states for each physical block and whether it applies to program or data accesses.
* Flash sectors can be combined to form larger memory segments. The thing to
keep in mind is the smallest amount that can be erased is a physical sector.
This may affect how code is partitioned for field upgrades.
* Continuous SARAM blocks can be combined to form a larger memory segment.
* Devices with DMA: only some blocks will be accessible by the DMA. Refer to the
data manual.
* Devices with CLA: only some blocks will be accessible by the CLA. Refer to the
data manual.
##Sections Description
This part of the linker command file tells the linker:
* Which software sections should be allocated to which memory regions
* Allows you to allocate to memory on a per-file basis
* Allows for separate load and run locations
An example sections description is shown below:
```c
/* Sections Description
Tell the linker where to allocate sections */
SECTIONS
{
.text: > H0SARAM PAGE 0
.ebss: > M0SARAM PAGE 1
.cinit: > H0SARAM PAGE 0
.stack: > M1SARAM PAGE 1
.reset: > H0SARAM PAGE 0, TYPE = DSECT
}
```
If you do not specify a generated section then the liker will try to place it
for you. This may result in it being placed somewhere you don't want it to be.
For example, the .ebss section may end up in flash which will not work! To
receive a warning message when the linker assigns unspecified sections use
the -w linker switch.
#Frequently Asked Questions
**Q: Why do I need a linker command file? Why doesn't the compiler take care of memory management?**
For simple examples it may not matter much what memory is used. But in embedded
processing it quickly does become important.
Here is a list of some things to consider when placing code/data:
* Speed: RAM is faster than Flash. Flash is faster than XINTF.
* Does it need to be stored in non-volatile memory like Flash?
* Is it time critical? Example: a time critical ISR stored in flash and copied to RAM.
* Some RAM may be accessible by a DMA module while other RAM is not.
* Use separate physical RAM blocks to avoid resource conflicts. On C2000 RAM blocks
are single access (SARAM).
* Is a resource on external memory?
* Should it be in memory with a cache or prefetch to improve performance?
* Does the memory have wait states in program space, data space, or both?
* Is it something that needs to be protected by the Code Security Module? Not
all memory is CSM protected.
The linker command file is how you describe your device to the tools and tell it
where you want different sections to go.
If you don't assign a particular section to a memory region then the tools will
indeed try to place it in any available memory. This may not be desired for the
above reasons. Because of this I suggest always linking with the -w flag so the
tools will tell you it is assigning a section to memory without your influence.
**Q: The linker says "placement fails for object" but the available memory is larger than the section**
This is most likely happening because the section is "blocked" by the compiler.
This means it needs to either fit completely within a page or begin at a page
boundary. Meeting that requirement does not allow it to fit within the space
available in the memory block. The compiler does this to optimize the data page
(DP) register load. For example, the compiler can safely load DP for an array
once and access all its elements (or the first 64-words) without having to
reload DP. If blocking is not enabled the compiler has to load DP for accessing
each element leading to much more inefficiencies in terms of code size and performance.
The alternative would be to generate a DP load before every direct memory access.
Obviously this could have a serious negative impact on code size. There is an
option though that will cause DP loads on every access, and disable blocking.
If you add the -md switch to your project it will disable blocking but impact
code size and performance - this is not recommended.
You can confirm that a particular section is "blocked" by looking at the .bss and
.usect directives in the assembly listing file and checking that the blocking
flag is set. The blocking flag is documented in the [C28x Assembly Language Tools Users Guide](https://www.ti.com/lit/pdf/spru513)
under "Uninitialized Sections".
**Q: The linker says "placement fails for object '.text' ". How can I make more memory available for .text?**
There are a few options - here are three:
***Option 1***
The linker command file (.cmd) specifies how memory will be allocated for the project.
You can try modifying the .cmd file to allow for a larger .text section.
For example, you can try combining contiguous RAM blocks or flash sectors to make
a larger block for code.
***Option 2***
You can "split" the .text section among multiple memory regions using the following syntax:
```c
.text : >> FLASHA | FLASHC | FLASHD, PAGE = 0
```
***Option 3***
You can tell the linker to allocate as a whole into the first memory range
in which it fits completely, by doing this:
```c
.text : > FLASHA | FLASHC | FLASHD, PAGE = 0
```
For any of these options, keep in mind that all blocks may not be equal in functionality - For example:
* On the Piccolo devices with Control Law Accelerator only some memory blocks can
be used by the CLA.
* On devices with the DMA not all memory can be accessed by the DMA.
* Most SARAM blocks are single access (zero wait state) but on some devices there
is a wait state in program memory. For example on 2833x the memories that the DMA
can use are zero wait in data space, but 1 wait in program space. This makes them
more suited towards pure data accesses.
**Q: In the linker command file, can I combine continuous flash blocks into one section?**
Yes - Flash sectors can be combined in the MEMORY section.
On the flash side, the thing to keep in mind is a sector is the smallest amount
of flash that can be erased at a time. Thus you may want to partition your code
such that code you upgrade (or don't upgrade) aligns to a sector.
***Option 1***
Combine two memory regions, in this case two sectors, into one:
Two sectors:
```c
MEMORY
{
//
// Individual sectors E and F called out in the MEMORY description
//
...
FLASHF : origin = 0x310000, length = 0x008000 /* on-chip FLASH */
FLASHE : origin = 0x318000, length = 0x008000 /* on-chip FLASH */
...
}
```
One combined memory region made of two sectors:
```c
MEMORY
{
//
// Sectors E and F merged into one in the MEMORY description
//
...
FLASHF_E : origin = 0x310000, length = 0x010000 /* on-chip FLASH F & FLASH E */
...
}
```
***Option 2***
Another option is to split the sections across multiple memory segments. This is
described in the [TMS320C28x Assembly Language Tools User's Guide (spru513)](https://www.ti.com/lit/pdf/spru513).
```c
SECTIONS
{
.text: { *(.text) } >> FLASHE| FLASHH
}
```
**Q: In the linker command file, I combine contiguous SARAM blocks into one section?**
Yes, you can do this by combining memory blocks or splitting the section across
memory blocks (described above for flash).
The thing to remember is the SARAM blocks are single access. So it is best to
partition code into a different physical SARAM block than data that code is
accessing. Keeping this partition will will improve performance.
**Q: My project is linking successfully. How do I find details about my project's memory utilization?**
After a project links successfully, a .map file can be generated which provides
information about memory utilization and symbol placement. Please see the
[TMS320C28x Assembly Language Tools User's Guide (spru513)](https://www.ti.com/lit/pdf/spru513) for more information.
**Q: I have a DSP/BIOS project. What should I know about linking?**
Please refer to this application note:
* [Running an Application from Internal Flash Memory on the TMS320F28xx DSP (spra958)](https://www.ti.com/lit/an/spra958l/spra958l.pdf)
* [Associated code](https://www.ti.com/lit/zip/spra958)