This article is for the TriCore toolset. A similar approach applies to our other products, like SmartCode, and Arm. Note that the keywords or naming conventions are different in Arm.
When you have a function that needs to be executed in RAM, a RAM-to-ROM copy loop is required to copy the function code from flash to the run-time address range. The startup code can do this automatically.
For this purpose, the copy keyword is applied to the LSL group definition:
section_layout :vtc:linear
{
// generate a ROM copy section and a copy table entry for the startup code
// in order to copy the code from ROM to RAM during startup
group INIT_CODE ( ordered, run_addr=mem:mpe:lmuram, copy )
{
select ".text.file_1.func_1";
}
}
Based on this keyword, the linker creates a copy table entry for the initialized function, and this is processed by the init function, called by the startup code, to copy the code from ROM to RAM.
If the startup code does not perform the initialization, the application code should do it later, changing the copy keyword to the overlay keyword. The initialization process itself is achieved using so-called linker labels to determine the start and end addresses of the ROM copy group. These labels are used in a copy loop executed by the application code.
The overlay keyword is also used for a different purpose. If you need multiple sections share the same RAM region, you can use overlay for this purpose. However, that use case is not addressed in this section.
section_layout :vtc:linear
{
/* generate a ROM copy section for initialized code */
group INIT_CODE (overlay, ordered, run_addr=mem:mpe:dspr0)
{
select ".text.file_1.func_1";
}
/* assign the ROM copy of the initialized section to a group to determine start and end address */
group ROM_COPY_INIT_CODE (ordered, load_addr)
{
select ".text.file_1.func_1";
}
}
To use linker labels in the C source code, extern declarations are added:
/* use a linker label to determine the start address of the group in flash */
extern __far unsigned short _lc_gb_ROM_COPY_INIT_CODE;
/* use a linker label to determine the end address of the group in flash */
extern __far unsigned short _lc_ge_ROM_COPY_INIT_CODE;
/* use a linker label to determine the start address of the overlay group in RAM memory */
extern __far unsigned short _lc_gb_INIT_CODE;
The copy loop to initialize the RAM function can look like:
/* load the start address of the ROM copy group into source pointer */
source = &_lc_gb_ROM_COPY_INIT_CODE;
/* load the start address of the RAM group into destination pointer */
dest = &_lc_gb_INIT_CODE;
/* initialize the RAM function using a copy loop */
for(loopcount=0; loopcount <
(&_lc_ge_ROM_COPY_INIT_CODE-&_lc_gb_ROM_COPY_INIT_CODE); loopcount++)
{
*dest++ = *source++;
}
+ Space mpe:vtc:linear (MAU = 8bit)
+-------------------------------------------------------------------------------------------------------------------------------+
| Chip | Group | Section | Size (MAU) | Space addr | Chip addr | Alignment |
|===============================================================================================================================|
| mpe:dspr0 | | INIT_CODE (364) | 0x0000000e | 0x70000000 | 0x0 | 0x00000002 |
| mpe:pflash0 | ROM_COPY_INIT_CODE | [.text.file_1.func_1] (365) | 0x0000000e | 0x80000024 | 0x00000024 | 0x00000002 |