This article is for the TriCore toolchain. A similar approach applies to our other toolchains as they use the same linker script language.
When a variable is initialized as shown below, the initialization value for this variable needs to be placed in flash memory:
int var_1 = 10;
The linker-generated copy table includes information about:
For more details about the C startup code, see Chapter 4.3. The C Startup Code in the TriCore User Guide.
If you need to place those ROM copy sections in a dedicated memory range, the LSL language offers different approaches to solve this:
The name of the ROM copy section is the same as the name of the RAM section, but the name of the ROM copy section is enclosed in square brackets [ ].
To select a ROM copy section in an LSL group, you need to use the full name, including the square brackets in the select line. Moreover, to have them parsed by the linker, you need to escape the square brackets using ‘\’.
For the C source line listed above, suppose the line is included in a file named file_1.c. The default near allocation value is set to zero to prevent any near addressable sections without using the __near qualifier. In this case, the default section name would be.data.file_1.var_1 which consists of:
<section name prefix>.<module name>.<variable name>
The section name prefixes used for the different types of sections are described in chapter 1.12. Compiler Generated Sections of the TriCore User Guide.
To
select the ROM copy section in an LSL group which is placed in ROM
memory (for example, starting at offset 0x100 in pflash0 memory), and to
have the RAM section placed (for example: starting at offset 0x200 in
dspr0 RAM) you can use the following syntax:
section_layout :vtc:linear
{
group MY_ROM_COPY_SECTIONS_RUN__ADDR ( ordered, run_addr = mem:mpe:pflash0[0x100] )
{
select "\[.data.file_1.var_1\]";
}
group MY_INITIALIZED_SECTIONS ( ordered, run_addr = mem:mpe:dspr0[0x200] )
{
select ".data.file_1.var_1";
}
}
The linker-generated map file includes the following entries:
* Sections
===========
+ Space mpe:vtc:linear (MAU = 8bit)
+-------------------------------------------------------------------------------------------------------------------------------------------+
| Chip | Group | Section | Size (MAU) | Space addr | Chip addr | Alignment |
|===========================================================================================================================================|
| mpe:dspr0 | MY_INITIALIZED_SECTIONS | .data.file_1.var_1 (3) | 0x00000004 | 0x70000200 | 0x00000200 | 0x00000002 |
| mpe:pflash0 | | .text._Exit.libc (190) | 0x00000004 | 0x80000028 | 0x00000028 | 0x00000008 |
| mpe:pflash0 | | table (196) | 0x00000030 | 0x8000002c | 0x0000002c | 0x00000004 |
| mpe:pflash0 | | .text..cocofun_1.libcs_fpu (6) | 0x00000010 | 0x8000005c | 0x0000005c | 0x00000002 |
| mpe:pflash0 | | .text..cocofun_2.libcs_fpu (8) | 0x00000010 | 0x8000006c | 0x0000006c | 0x00000002 |
| mpe:pflash0 | | .text..cocofun_3.libcs_fpu (16) | 0x00000010 | 0x8000007c | 0x0000007c | 0x00000002 |
| mpe:pflash0 | | .text..cocofun_4.libcs_fpu (15) | 0x00000010 | 0x8000008c | 0x0000008c | 0x00000002 |
| mpe:pflash0 | | .text..cocofun_5.libcs_fpu (10) | 0x0000000a | 0x8000009c | 0x0000009c | 0x00000002 |
| mpe:pflash0 | | .text.__init_sp.libcs_fpu (13) | 0x00000016 | 0x800000a6 | 0x000000a6 | 0x00000002 |
| mpe:pflash0 | | .text._c_init.libcs_fpu (73) | 0x0000000c | 0x800000bc | 0x000000bc | 0x00000002 |
| mpe:pflash0 | | .text._ldmst_clear_byte.libcs_fpu (70) | 0x0000002e | 0x800000c8 | 0x000000c8 | 0x00000002 |
| mpe:pflash0 | | .text.file_1.main (2) | 0x00000008 | 0x800000f6 | 0x000000f6 | 0x00000002 |
| mpe:pflash0 | MY_ROM_COPY_SECTIONS_RUN__ADDR | [.data.file_1.var_1] (197) | 0x00000004 | 0x80000100 | 0x00000100 | 0x00000002 |
| mpe:pflash0 | | .text._c_init_entry.libcs_fpu (72) | 0x00000120 | 0x80000104 | 0x00000104 | 0x00000002 |
| mpe:pflash0 | | .text._ldmst_copy_byte.libcs_fpu (71) | 0x00000044 | 0x80000224 | 0x00000224 | 0x00000002 |
This
makes the linker select the ROM copy of initialized sections. When
doing this, you need to remove the square brackets to select the
section:
section_layout :vtc:linear
{
group MY_ROM_COPY_SECTIONS_LOAD_ADDR ( ordered, load_addr = mem:mpe:pflash0[0x100] )
{
select ".data.file_1.var_1";
}
group MY_INITIALIZED_SECTIONS ( ordered, run_addr = mem:mpe:dspr0[0x200] )
{
select ".data.file_1.var_1";
}
}
The zip file ROM_copy_placement includes a buildable example using a command line invocation. It can be extracted into an empty folder, and the gen.bat batch file can be invoked to build the example.