TRICORE TC275使用Tasking编译时copytable错误:含义及修复咨询
Alright, let's tackle this Tasking linker error and break down what's going on with copytable and how to fix the issue.
copytable? In the TRICORE Tasking compilation environment, copytable is a linker-generated data structure that manages initialized global/static variables that need to be copied from non-volatile storage (like Flash) to RAM during program startup.
Here's why this is necessary: Flash is read-only, so any variable that's initialized with a value (e.g., int task_status = 1;) can't be modified directly in Flash. The linker collects all such variables, records their source address (Flash location of the initial value), target address (RAM location where the variable will live), and copy length into the copytable. By default, the compiler-provided startup code iterates over this table and performs the copy before main() runs.
ltc E122 Error The error occurs because you've enabled the --user-provided-initialization-code linker option, which tells the linker: "I'm handling startup initialization myself, don't use the default code". But the linker still detects variables (related to task1) that need to be copied via copytable—and you haven't signaled that you'll handle this copy process manually.
You have two clear solutions depending on your needs:
Option 1: Keep custom initialization, and handle copytable manually
If you truly need a custom startup flow, you'll need to add code to process the copytable yourself:
- Confirm linker script setup: Your existing linker script already defines
copytable (align = 1 << 2, copy_unit = 1, dest = linear);—this is correct, and the linker will generate two global symbols:__copytable_start__(start of the table) and__copytable_end__(end of the table) (check Tasking docs for exact symbol names if these don't match). - Add copy logic to your custom startup code:
// Define the structure of a copytable entry (matches Tasking's format) typedef struct { void* src_addr; // Source address in Flash void* dest_addr; // Target address in RAM size_t length; // Number of bytes to copy } CopyTableEntry; // Declare the linker-generated symbols extern CopyTableEntry __copytable_start__; extern CopyTableEntry __copytable_end__; void custom_copy_table_init(void) { CopyTableEntry* current_entry = &__copytable_start__; while (current_entry < &__copytable_end__) { // Copy bytes one by one (since your script uses copy_unit=1) uint8_t* src = (uint8_t*)current_entry->src_addr; uint8_t* dest = (uint8_t*)current_entry->dest_addr; for (size_t i = 0; i < current_entry->length; i++) { dest[i] = src[i]; } current_entry++; } } - Call this function early in startup: Make sure
custom_copy_table_init()runs before any code that accesses the initialized variables (and definitely beforemain()).
Option 2: Remove the custom initialization option (if you don't need it)
If you added --user-provided-initialization-code by mistake or don't actually need a custom startup flow, simply remove this flag from your LINK_OPT settings. The linker will revert to using the default startup code, which automatically handles the copytable copy process, and the error will disappear.
Quick Check: Audit task1 Variables
Since the error specifically mentions task1, take a look at the variables associated with it:
- Are there initialized global/static variables (e.g.,
static int task_counter = 0;)? If these don't need an initial value, declare them uninitialized (static int task_counter;)—this will exclude them from thecopytableentirely and avoid the need for copying.
内容的提问来源于stack exchange,提问作者Lkaf Temravet

