This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CL2000链接器生成错误的自动初始化数据

Guru**** 2563960 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/1190185/cl2000-linker-generating-wrong-autoinitialization-data

我需要使用一些默认值为内部变量配置固定地址。 我在指定的地址正确地获取变量、但某些值初始化为零、而不是指定的值。 经过一些调查、我发现链接器为初始化数据生成了错误的大小。

我创建了简单的程序来复制它(使用 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;
}

链接器映射中的相关输出似乎正确:

链接器生成的复制表

_TI_cinit_table @ 00082120记录:6、大小/记录:4、表大小:24
   .data:load addr=000820f0、load size=00000009字节、run addr=0000aa00、run size=0000000a 字节、compression=lzss
   .TI.bound:A4:load addr=000820fa、load size=00000008字节、run addr=0000a807、run size=00000004字节、compression=copy
   .TI.bound:A3:load addr=00082102、load size=00000007字节、run addr=0000a804、run size=00000003字节、compression=copy
   .TI.bound:A2:load addr=0008210a、load size=00000006字节、run addr=0000a802、run size=00000002字节、compression=copy
   .TI.bound:a0:load addr=00082110、load size=00000005字节、run addr=0000a800、run size=00000001字节、compression=copy
   .TI.bound:A1:load addr=00082116、load size=00000005字节、run addr=0000a801、run size=00000001字节、compression=copy

但是、当我检查生成的二进制文件时、我发现存在不一致(例如至少两个16位"字节"的饱和)、这会导致为16位变量复制两个16位字节而不是一个字节、这会导致下一个地址意外归零(用于不同变量):

来自生成的二进制文件的数据:

uint16_t A4[4]={64、65、66、67};

   @0820FA = 0x1   //类型
   @0820FB = 0x0
   @0820FC = 0x4   //长度-正确
   @0820FD = 0x0
   @0820FE = 0x40
   @0820FF = 0x41
   @082100 = 0x42
   @082101 = 0x43

uint16_t A3[3]={48、49、50};

   @082102 = 0x1  //类型
   @082103 = 0x0
   @082104 = 0x3  //长度-正确
   @082105 = 0x0
   @082106 = 0x30
   @082107 = 0x31
   @082108 = 0x32
   @082109 = 0x0


uint16_t a2[2]={32、33};

   @08210A = 0x1  //类型
   @08210B = 0x0
   @08210C = 0x2  //长度-正确
   @08210D = 0x0
   @08210E = 0x20
   @08210F = 0x21

uint16_t a1[1]={16};

   @082110 = 0x1  //类型
   @082111 = 0x0
   @082112 = 0x2  //长度-应为1
   @082113 = 0x0
   @082114 = 0x100
   @082115 = 0x0

uint16_t a0 = 0x100;

   @082116 = 0x1  //类型
   @082117 = 0x0
   @082118 = 0x2  //长度-应为1
   @082119 = 0x0
   @08211A = 0x10
   @08211b = 0x0

是否存在我缺少的配置、或者是否存在错误并存在一些良好的解决方法?

为了进行完整说明、我真正需要创建几个16位变量、这些变量位于无间隙的指定地址上。 (我想避免创建结构)。

我使用的是 code composer 9.3、但12.2也存在相同的问题。

从生成控制台日志:

调用:C2000链接器
"/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=fpu32 --display_error_number-abi=-abi=vus-link_exclus-rom-rom-out-link_ram_ram_ram_ram_ram_test-out.ates=out.xml-r3210.at_ram_ram_ram_ram_ram_ram_ram_off-out.ates=-out.at_ram_ram_ram_ram_ram_line_display-out.at_line_display_ram_ram_ram_ram_lines=-out.ates=-out.at_ram_ram_ram_ram_ram_ram_ram_ram_ram_ram_ram_ram_off-out.at_ram.ates=-/opt/ti/ccs1220/ccs/tools/compiler/ti-cgt-c2000_22.6.0.LTS/include /opt/ti/ccs1220/ccs/tools/compiler/ti-cgt-c2000_22.6.0.LTS/lib  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="550740" URL"~/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/1190185/cl2000-linker-generating-wrong-autoinitialization-data "]是否存在错误[/quot]

    不幸的是、是的。  已有报告。  请参阅 EXT_EP-10875

    [引用 userid="550740" URL"~/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/1190185/cl2000-linker-generating-wrong-autoinitialization-data "]是否存在一些有效的变通办法?

    我有一个权变措施供您考虑。

    该问题仅适用于标量全局变量。  这是一个 C 宏、它定义了一个不初始化的变量、并将其分配给特定地址。

    // DNVA : Define No-init scalar Variable at a specific Address
    #define DNVA(type, name, address) \
        type name __attribute__((noinit, location(address)))

    您可以对#pragma 语句执行相同的操作。  但需要其中两个、很难将其封装到这样的方便宏中。

    下面是一个如何使用宏的示例。

    DNVA(uint16_t, a0, 0xa800);

    变量未初始化。  为此、请利用引导挂钩函数 _system_post_cinit。  将此函数添加到项目中的源文件中。

    void _system_post_cinit()
    {
        a0 = 0x100;
    }

    当然、更改它以初始化受此问题影响的所有全局标量变量。

    要了解有关变量属性的更多信息、 请在 C28x 编译器手册中搜索 标题为"变量属性"的子章节。  要了解有关_system_post_cinit 的更多信息、请在同一手册中搜索标题 为"用于系统预初始化的引导挂钩函数"的子章节。

    谢谢、此致、

    乔治

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您的快速回答。 我正在考虑类似的权变措施,将变量初始化放在 main()的开头,但使用_system_post_cinit 看起来更好。

    谢谢、此致、

    Branislav