I need to configure fixed address for internal variables with some default values. I correctly get variables at specified addresses, but some values are initialized to zero instead of specified value. After some investigation I found linker is generating wrong size for intialization data.
I created simple program to reproduce it (using eabi):
#include <stdint.h>
uint16_t a4[4] = {64,65,66,67};
uint16_t a3[3] = {48,49,50};
uint16_t a2[2] = {32,33};
uint16_t a1[1] = {16};
uint16_t a0 = 0x100;
#pragma LOCATION( a0, 0xA800 )
#pragma LOCATION( a1, 0xA801 )
#pragma LOCATION( a2, 0xA802 )
#pragma LOCATION( a3, 0xA804 )
#pragma LOCATION( a4, 0xA807 )
int main(void)
{
// some variable access to avoid optimization out
a4[0] = a0; a3[0] = a4[0]; a2[0] = a3[0]; a1[0] = a2[0]; a0 = a1[0];
return 0;
}
relevant output in linker map seems to be correct:
LINKER GENERATED COPY TABLES
__TI_cinit_table @ 00082120 records: 6, size/record: 4, table size: 24
.data: load addr=000820f0, load size=00000009 bytes, run addr=0000aa00, run size=0000000a bytes, compression=lzss
.TI.bound:a4: load addr=000820fa, load size=00000008 bytes, run addr=0000a807, run size=00000004 bytes, compression=copy
.TI.bound:a3: load addr=00082102, load size=00000007 bytes, run addr=0000a804, run size=00000003 bytes, compression=copy
.TI.bound:a2: load addr=0008210a, load size=00000006 bytes, run addr=0000a802, run size=00000002 bytes, compression=copy
.TI.bound:a0: load addr=00082110, load size=00000005 bytes, run addr=0000a800, run size=00000001 bytes, compression=copy
.TI.bound:a1: load addr=00082116, load size=00000005 bytes, run addr=0000a801, run size=00000001 bytes, compression=copy
but when I check generated binary file I see there inconsistency (like saturation for minimum of two 16-bit "bytes"), which is causing to copy two 16-bit bytes for 16-bit variables instead of one byte what is causing unintended zeroing of the next address (which is used for different variable):
data from generated binary:
uint16_t a4[4] = {64,65,66,67};
@0820FA = 0x1 // type
@0820FB = 0x0
@0820FC = 0x4 // length - correct
@0820FD = 0x0
@0820FE = 0x40
@0820FF = 0x41
@082100 = 0x42
@082101 = 0x43
uint16_t a3[3] = {48,49,50};
@082102 = 0x1 // type
@082103 = 0x0
@082104 = 0x3 // length - correct
@082105 = 0x0
@082106 = 0x30
@082107 = 0x31
@082108 = 0x32
@082109 = 0x0
uint16_t a2[2] = {32,33};
@08210A = 0x1 // type
@08210B = 0x0
@08210C = 0x2 // length - correct
@08210D = 0x0
@08210E = 0x20
@08210F = 0x21
uint16_t a1[1] = {16};
@082110 = 0x1 // type
@082111 = 0x0
@082112 = 0x2 // length - should be 1
@082113 = 0x0
@082114 = 0x100
@082115 = 0x0
uint16_t a0 = 0x100;
@082116 = 0x1 // type
@082117 = 0x0
@082118 = 0x2 // length - should be 1
@082119 = 0x0
@08211A = 0x10
@08211B = 0x0
Is there some configuration which I'm missing or is it bug and exists some good workaround?
For complete description, what i really need is to create several 16-bit varaiables which are on specified addresses without gap. (I would like to avoid creating structs).
I was using code composer 9.3, but same issue is also with 12.2.
from build console log:
Invoking: C2000 Linker
"/opt/ti/ccs1220/ccs/tools/compiler/ti-cgt-c2000_22.6.0.LTS/bin/cl2000" -v28 -ml -mt --cla_support=cla1 --float_support=fpu32 --tmu_support=tmu0 --vcu_support=vcu2 --advice:performance=all -g --diag_warning=225 --diag_wrap=off --display_error_number --abi=eabi -z -m"test.map" --stack_size=0x200 --warn_sections -i"/opt/ti/ccs1220/ccs/tools/compiler/ti-cgt-c2000_22.6.0.LTS/lib" -i"/opt/ti/ccs1220/ccs/tools/compiler/ti-cgt-c2000_22.6.0.LTS/include" --reread_libs --diag_wrap=off --display_error_number --xml_link_info="test_linkInfo.xml" --rom_model -o "test.out" "./main.obj" "../28375S.cmd" -lrts2800_fpu32_eabi.lib