Retrieve information about the copy table content for initialized and zeroed global variables

26-Nov-2024

This article is for the TriCore toolset.

According to the ISO C standard, global variables need to be initialized.

If a variable is not initialized as shown below, it will be initialized with zeroes.

int var_1;

The initialization is conducted during the execution of the startup code.

For initialized variables, the initialization value of each variable needs to be copied from its address in ROM to the run-time location of the variable in RAM.

For non-initialized variables, the run-time location of the variable in RAM is initialized with zeroes.

This initialization task is typically conducted by processing a linker-generated copy table. The copy table is located in ROM and includes information about the source address of an init value of a variable in ROM, the destination address in RAM, and the number of bytes that need to be copied from source to destination. For non-initialized variables, the copy table includes a destination entry of the variable in RAM and the number of bytes that need to be initialized with zeroes. For example, for an int type variable for a 32-bit architecture, 4 bytes need to be zeroed to initialize the variable with zeroes.


Prevent the startup code from zeroing a non-initialized variable

It is possible to prevent the startup code from zeroing a non-initialized variable. This can be useful if, for example, battery-buffered RAM is used and the variable's value remains valid after a reset of the application.


Method 1:

Use pragma noclear to prevent the zero initialization of selected variables.


Method 2:

Add a scratch attribute to the section including the variable via a linker LSL file entry like:

section_layout :vtc:linear
{
group NOCLEAR_FAR_DATA (ordered, run_addr=mem:mpe:dspr0, attributes=rws ) // 's' is for scratch
{
select ".bss.var_1";
}
}

Figure out details about the copy table

To determine the details of the copy table the linker created, you can dump the copy table section using the HLL Object Dumper (hldumptc), which is included in our TriCore and SmartCode tools installation.

After the linker creates an ELF output file, you can use the following invocation to dump the copy table section which is named table:

hldumptc project_name.elf -F2 --sections=table -o copytable_dump.txt

The content of a dumped copy table section looks like:

---------- Section dump ----------

.sdecl 'table',DATA AT 0x80000034
.sect 'table'
address-label address raw-data action source destination size(dec) min-write-size
_lc_ub_table 80000034 00000002 50000808 00000000 00000008 clear 50000808 8 byte
80000044 00000001 50000810 80000024 00000008 copy 80000024 50000810 8 byte
80000054 00000002 70000004 00000000 00000004 clear 70000004 4 byte
80000064 00000000 stop

Because a single copy or clear entry in the copy table needs an overall 16 bytes, the size of the copy table also depends on the number of clustered initializations. If multiple variables that need to be initialized are grouped, the linker will produce a single copy table entry to initialize a group of variables, which is more efficient and reduces the copy table size.


Example:

The zip file copytable_content_evaluation includes a buildable example using a command line invocation. You can extract it into an empty folder.

The HLL dump tool (hldumptc) is used to dump the copy table section content into a human-readable format. The copy table includes copy and clear entries for sections that need to be initialized or cleared (initialized with zeroes). You can compare the copy table dump files of the individual use cases, to verify the changes in the copy table content.
The example includes two use cases:

  • One shows an optimized order of variables when non-initialized variables are grouped in a contiguous memory range and initialized variables are grouped in another contiguous memory range
  • The second use case shows an unfavorable order of variables when the order of variables is intermixed having a non-initialized variable followed by an initialized one followed by a non-initialized one. This order has been enforced due to a specification in the linker LSL file of the application.

The dumped copy table content of both versions (copytable_good_order_dump.txt and copytable_bad_order_dump.txt) shows the differences.
The gen.bat batch file can be invoked to create the two versions for later comparison.

A prerequisite is to add the path to the ctc\bin sub-directory which includes the binaries of the compiler product to the PATH environment variable. This can be achieved by using the following command in a command prompt window.

set PATH=<path to the ctc\bin folder>;%PATH%

For example, if the TriCore tools have been installed in the directory C:\Program Files\TASKING\TriCore v6.3r1 then use the command:

set PATH=C:\Program Files\TASKING\TriCore v6.3r1\ctc\bin;%PATH%

 

More resources

Was this answer helpful?