Memory usage information included in a map file

15-Nov-2024

The available on-chip memory of an Infineon AURIX family derivative is distributed across various memory areas.

You need to be aware of the extent to which the application code and data use individual memory ranges. This can indicate potential bottlenecks that may require you to adjust the application code or linker LSL file in terms of section placement.


Memory definitions

The Infineon User Manual for a TriCore derivative includes a description of the memory map where the ranges of all available on-chip memories are specified. This information is used to create the <derivative name>.lsl file for our TriCore tools. An example of the definition of the DSPR0 memory extracted from the file named tc39xb.lsl:

memory dspr0 // Data Scratch Pad Ram CPU0
{
mau = 8;
size = 240k;
type = ram;
priority = 1;
exec_priority = 0;
map (dest=bus:tc0:fpi_bus, dest_offset=0xd0000000, size=240k, priority=1, exec_priority=0);
map (dest=bus:sri, dest_offset=0x70000000, size=240k);
}

This defines the size of the memory (240kB) and the memory ranges to which it is mapped. For the core local memories like the DSPR and PSPR memories, the CPU supports linear address space mapping using the SRI bus, and a core local address space mapping using the FPI bus. Physically the two address ranges fully overlap. In other words, if TriCore core 0 writes to address 0x70000000, it is equal to writing to address 0xD0000000 and vice versa.

If core 1 writes to address 0xD0000000, this is equal to writing to the SRI bus address 0x60000000.

The DSPR1 memory definition is included in the tc39xb.lsl file shows the following mapping:

map (dest=bus:tc1:fpi_bus, dest_offset=0xd0000000, size=240k, priority=1, exec_priority=0);
map (dest=bus:sri, dest_offset=0x60000000, size=240k);

Memory usage table included in the map file

The linker-generated map file includes a Used Resources section which contains the Memory usage in bytes table. In case you cannot locate this section in your map file, you can review the --map-file-format (-m)option used in the linker invocation. The memory usage information is only included if the following sub-option is enabled.

+/-memory   m/M   Include memory usage information

Suppose the --map-file-format linker option is not used at all in the invocation, and the default map file format setting is active, which contains the Memory usage section.
Let’s have a closer look at an example snippet of a 
Memory usage in bytes section included in a map file for a TC39xB application.

* Memory usage in bytes
========================
+-----------------------------------------------------------------------------+
| Memory          | Code      | Data      | Reserved  | Free      | Total     |
|=============================================================================|
| mpe:dflash0     |       0x0 |       0x0 | 0x0100000 |       0x0 | 0x0100000 |
...
| mpe:dlmucpu0    |       0x0 | 0x00000c0 |       0x0 | 0x000ff40 | 0x0010000 |
...
| mpe:dspr0       |       0x0 | 0x0000100 | 0x0005400 | 0x0036b00 | 0x003c000 |
...
| mpe:pflash0     | 0x0001698 | 0x000283b |       0x0 | 0x02fc12d | 0x0300000 |
...
| mpe:pspr1       | 0x0000032 |       0x0 |       0x0 | 0x000ffce | 0x0010000 |
...
|-----------------------------------------------------------------------------|
| Total           | 0x00016ca | 0x0003243 | 0x05f2400 | 0x12692f3 | 0x1860000 |
+-----------------------------------------------------------------------------+
  • The entry for the dflash0 memory shows that neither code nor data sections are located within this memory range. The size of the dflash0 memory is 1MB and this memory is by default reserved. This prevents the linker from placing any sections in that memory range by default. If required, it is possible to place sections in the dflash0 memory by assigning them to an LSL group that is placed in that memory. The memory definition for this memory is included in the tc39xb.lsl file with the following entry to reserve the complete memory range:
type = reserved nvram;

  • The entry for the dlmucpu0 memory shows that 0xC0 bytes of data are located within that memory. As the overall memory size of the dlmcpu0 memory is 64kB, the remaining free memory would be 0xFF40 bytes.
  • The entry for the dspr0 memory shows that 0x100 bytes are used for data sections, 0x5400 bytes are reserved and 0x36b00 bytes are free from the overall available memory of 0x3C000 (240kB).
Sections that can be counted as reserved sections
    • A reserved entry in an LSL file:
    group MY_RESERVE ( ordered, run_addr = mem:mpe:dspr0[0x4000] )
    {
    reserved "RESERVED_DSPR0_RANGE" ( size = 2k );
    }
    • An empty output section with a defined size or blocksize: This may exist when the section(s) that shall be assigned to that output section does not exist in the application data like:

    group MY_GROUP ( ordered, run_addr = mem:mpe:dspr0 )
    {
       section "MY_OUTPUT_SECTION" ( attributes=rw, blocksize = 4 )
       {
          select ".bss.my_section_name";
       }
    }

    If the section(s) with the name .bss.my_section_name exists in the application data, they will be assigned to this output group. If they do not exist, the output group will have a size of 4 bytes and this size will be counted as reserved memory.

    • .alignment_protection sections: This kind of section is generated when an LSL group is defined using the contiguous and fill keywords. As a result, the linker will ensure that possible alignment gaps are not filled up with other unconstrained sections, but the space in between is always reserved. For example, if a char type variable that starts at an even address is followed by an int type variable, the int type variable needs to start at an even address, which is a hardware requirement of the load word/store word instructions used to access an int data type. As a consequence, there is a gap between the char and the int type variable. This gap could be filled up by, for example, another char type variable that is not assigned to any other LSL group. Then the linker is free to ‘squeeze’ this variable in between the char and the int variable, to fill up this alignment gap. The char type variables can be located at an odd or an even address. To ensure that no other sections that are not part of the LSL group selection are inserted like this, the contiguous and fill keyword is applied. If the fill keyword is not applied, the linker will not emit .alignment_protection entries in the map file. However, if there is a gap between two adjacent sections the linker will also add the size of this gap to the reserved range.
    • Boot Mode Header (BMHD) ranges: Boot Mode Headers are evaluated during the startup process of the CPU.
    • Context Save Area (CSA) ranges: The context save area is used to store the upper and/or lower context, for example, during a task switch. A CSA consists of a defined set of data and address registers D[x] and A[x], plus a few other registers. The size of a single CSA is 64 bytes. By default, 64 CSAs are reserved per TriCore core (4kB).
    • Interrupt and user stack range: The stack is needed by the compiler, for example, to store intermediate results or to store function local volatile variables. The user stack is used by default, and the interrupt stack is used within an interrupt service function or a trap function.
    • Scratch sections: A scratch section is a non-initialized variable that is not cleared (initialized with zeroes) by the C startup code. These kinds of sections should be counted as data sections, but due to a tool issue, they are counted as reserved sections.

The reference number for the issue logged to document this behavior is: TCVX-43538 Linker counts scratch sections as reserved sections under 'Memory usage in bytes'

Suppose you need to figure out how many of those scratch sections are erroneously counted as reserved sections. In that case, you can invoke the elfdump tool included in our TriCore product which processes the ELF file of the application. The Section Headers part of the elfdump content includes a column named Flags. An N entry is added under Flags when the section is a noclear section. This allows you to locate the scratch sections which are counted as reserved but should be counted as data.

An example of the elfdump snippet:    

[ Nr] Name           Type   Addr     Off    Size   ES Flags    Lk Inf Al Addr.spc
...
[ 6] .bss.file_1.var NOBITS 90000000 000000 000800 00 WA    sN 00 000 02
...

Here the section named .bss.file_1.var with a size of 0x800 bytes is a scratch section.

  • The entry for the pflash0 memory shows that 0x1698 bytes are used for program code and 0x283b bytes are used for const data. ROM copy sections including the content of initialized code or data sections are counted as data sections too. A ROM copy section name is enclosed in square brackets in the map file. For example:

    mpe:pflash0 [.data.file_1.f_arr_2] (585)| 0x00000080 | 0x800000f8 | 0x000000f8 | 0x00000002
    mpe:lmuram0 .data.file_1.f_arr_2 (8)    | 0x00000080 | 0x900401d4 | 0x000001d4 | 0x00000002
    The first entry is a simplified line extracted from the Locate Result part of a map file which provides information about the placement of the ROM copy of an initialized data section and the second entry shows the RAM location of the data section itself.

    Other internal compiler-generated sections that are counted as data sections are:
    • Initializers: *.<n>.ini.*
    • String literals: *.<n>.str.*
    • Compound literals: *.<n>.lit.*
    • Constants: *.<n>.cnt.*
    • Switch lookup tables: *.<n>.lkp.*
    • Switch jump tables: *.<n>.jmp.*

  • The entry for the pspr1 memory shows that 0x32 bytes are used for program code. Since the pspr1 memory is RAM memory, this is typically initialized code which is copied from flash to RAM before it’s executed in RAM.
  • The entry named Total includes the summary of all sections per type.

The tc39xb.lsl file used for this example defines an overall of 4MB of emulation RAM memory. If a production type version of the derivative is used, this memory is not available.


More resources

Was this answer helpful?