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.

[参考译文] 编译器/TMS320C6657:外部存储器中的全局变量未初始化为零。

Guru**** 2587365 points
Other Parts Discussed in Thread: AM5728, BEAGLEBOARD-X15, TM4C1294NCPDT, SEGGER

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

https://e2e.ti.com/support/tools/code-composer-studio-group/ccs/f/code-composer-studio-forum/605326/compiler-tms320c6657-global-variables-in-external-memory-not-initialized-to-zero

部件号:TMS320C6657
主题中讨论的其他部件:AM5728BeagleBoard-X15TM4C1294NCPDTSEGGER

工具/软件:TI C/C++编译器

标题所说的。  根据ANSI C标准,所有静态变量都应初始化为零或空。  是的,我们正在使用EABI。

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

    根据ANSI C标准,所有静态变量都应初始化为零或空。 [/QUOT]要在所有情况下都在嵌入式目标上工作,可能需要从引导加载程序执行一些操作。 尝试了解问题的一些问题:

    1)如果Initialization Model链接器选项是--ROM_model,则C运行时库启动代码将零初始化全局变量。 如果 Initialization Model linker选项是--ram_model,则引导加载程序负责对全局变量进行零初始化。 使用哪个初始化模型选项?

    2)线程标题显示“外部内存中的全局变量未初始化为零”。 内部存储器中的全局变量是否已正确初始化? 是否在加载程序之前初始化了外部存储器接口?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    1.-柱塞型号。 "bootloader"是Blackhawk 560 USB仿真器。

    2.内存中的“某些”全局变量已正确初始化。 这肯定是编译器或链接器的问题。 我们创建了一个称为"int_data_SRAM"的数据段,它是设备上的L2内存。 如果我们使用#pragma set_data_section("int_data_sRAM"),则会初始化放置在该部分中的任何全局变量。 但是,如果我们使用#pragma set_data_section(),将数据部分设置为默认值(也是L2内存),则不会初始化全局变量。

    我确信有一个设置可以控制这一点,但我们花了几天时间浏览成千上万的编译器和链接器开关和选项,却找不到任何内容。

    如果我们专门初始化变量,即int my_global_var =0;则它确实会被初始化,但我们不应该这样做。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    I sure therealthing a setting to control this but we says ways finding the dists of compiler and linker switches and options, and unfind thing.[/QUOT]我创建了以下程序来测试已初始化和未初始化的全局变量的行为:

    #include <stdio.h>
    #include <stdbool.h>
    
    #define NUM_DATA_O词语32
    
    int uninitialized_data[NUM_DATA_字数];
    int initialized_data[NUM_DATA_字数]=
    {
    1,2,3,4,5, 6,7,8,9,10, 11,12,13,14,15,16, 17,18,19,20,21, 22,23,24,25,26, 27,28,29,30,31, 32
    };
    
    int main(void){
    
    内部索引;
    int num_Expected值;
    
    num_Expected值= 0;
    对于(index = 0;index < NUM_DATA_JESS;index++)
    {
    IF (未初始化的数据[index]== 0)
    {
    num_Expected值+;
    }
    }
    printf ("num Expected uninitialized_values=%d\n",num_Expected _values);
    
    num_Expected值= 0;
    对于(index = 0;index < NUM_DATA_JESS;index++)
    {
    IF (initialized_data[index]==(index + 1))
    {
    num_Expected值+;
    }
    }
    printf ("num Expected initialized_values=%d\n",num_Expected _values);
    
    对于(index = 0;index < NUM_DATA_JESS;index++)
    {
    未初始化的_data[index]++;
    initialized_data[index]+;
    }
    
    返回0;}
    

    测试使用:

    1)在AM5728的ARM Cortex-A15和C66内核中运行相同的程序。

    2) BeagleBoard-X15,与Blackhawk USB560-M仿真器连接,20引脚JTAG电缆,用于下载程序。

    3) CCS  7.2。0.0.0013万。

    4)编译器TI v Cortex-A15程序的17.3 .0.STS。

    5)编译器TI v 8.1 4,用于C66程序。

    6)存储在AM572.8512万KB L3 OCMC SRAM1中的程序,即内部设备存储器。

    结果是:

    A)当Cortex-A15和C66程序设置为--ROM_MODEL时, 在 从CCS调试器加载或重新加载程序时,未初始化的数据[]和初始化的数据[]数组被设置为预期值。 使用 --rom_model意味着编译器运行时库中的代码启动零初始化具有静态持续时间且没有初始化程序的变量。

    B)当 Cortex-A15和C66程序设置为--ram_model时, 当程序从CCS调试器加载或重新加载时,initialized_data[]数组被设置为预期值。 但是, 在 从CCS调试器加载或重新加载程序时,未初始化的数据[]未进行零初始化。 重新加载程序时 ,未初始化的数据[]数组的内容与上次运行的内容相同。 使用--ram_model意味着CCS调试器负责对 静态持续时间的变量进行零初始化,而这些变量在加载程序时没有初始化程序。

    以C66为例,当使用--ram_model编译时,链接程序映射文件显示 未初始化的数据数组位于地址0x4030.842万:

    远 40.3082万 403082e0.0001万c8 未初始化
    40.3082万e0 00000140000000140 (.common:__TI_tmpnams)
    40.3084万20 000000802万00080</s>0.008万 (.common:uninitialized_data)
    40.3084万a0 00000008000000008 (.common:parmbuf) 

    查看TI链接器生成的ELF程序头,可以看到:

    $ readelf.exe -l /cygdrive/C/users/MR_halfword_v7/AM5728_C66_global_vars/Debug/AM5728_C66_global_vars.out
    
    Elf5728 Elf文件类型为EXEC (可执行文件)
    入口点0x4.0306万c20
    有6个程序标头,从偏移18.9608万
    
    开始程序标头:
    类型 偏移VirtAddr PhysAddr FileSiz MemSiz Flg对齐
    负载 0x0.004万 0x4030万 0x4030万 0x06f40 0x06f40 R E 0x20
    负载 0x006f80 0x4.0306万f40 0x4.0306万f40 0x0万 0x0.1万 RW 0x8
    负载 0x006f80 0x4.0307万f40 0x4.0307万f40 0x0039c 0x0.0568万 RW 0x8
    负载 0x0.732万 0x40.3084万a8 0x40.3084万a8 0x0.0174万 0x0.0174万 R 0x8
    负载 0x0.7498万 0x4030.862万 0x4030.862万 0x0万 0x0.012万 RW 0x8
    负载 0x0.7498万 0x4030.874万 0x4030.874万 0x0.0038万 0x0.0038万 R 0x4
    
    段到段映射:
    段段段...
    00 文本
    01. .stack.sysmem
    2 far .fardata
    03. const
    04 首席信息官
    05. 开关 

    起始地址 为0x4.0307万f40的装载段的 FileSiz为 0x0039c,MemSiz为 0x0.0568万。 由于MemSiz比 FileSiz大,我的理解是,CCS调试器加载程序时,它应该为零,以填充(加载地址+ FileSiz)所覆盖的内存范围 。 (加载地址+ MemSiz -1),这是内存地址0x40.3082万dc .. 0x40.3084万a7,它包含未初始化的数据数组的位置。 因此,TI链接器已正确生成ELF程序标头,该标头应导致CCS调试器在 加载程序时对未初始化的数据数组执行零初始化。

    因此,问题可能出在CCS调试器中,也可能出在 Blackhawk USB560-M仿真器的驱动程序中。

    附加了示例程序。

    e2e.ti.com/.../AM5728_5F00_A15_5F00_global_5F00_vars.zip

    e2e.ti.com/.../AM5728_5F00_C66_5F00_global_5F00_vars.zip

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这也是我的结论,无论是调试器还是仿真器驱动程序。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    ----这也是我的结论,调试器或仿真器驱动程序。[/QUOT]创建了我的测试程序的一个版本,它在与Segger J-Link连接的TM4C1294NCPDT中运行。 该程序使用TI ARM 17.3 v.0编译,程序设置为使用--ram_model从SRAM执行。 选择此设备和调试探测器后,可以使用CCS和IAR调试程序加载相同的ELF .OUT文件。

    使用CCS 7.2 调试器下载程序时 ,如果 从0.0.0013万 调试器加载或重新加载程序,则会将initialized_data[]数组设置为预期值。 但是, 在 从CCS调试器加载或重新加载程序时,未初始化的数据[]未进行零初始化。 重新加载程序时 ,未初始化的数据[]数组的内容与上次运行的内容相同。

    当使用IAR嵌入式工作台IDE - ARM 8.11 2下载同一程序时,   加载或重新加载程序时,未初始化的数据[]和已初始化的数据[]数组被设置为预期值。

    示例程序的ELF程序标题为:

    $ readelf.exe -l /cygdrive/C/users/MR_halfword_v7/TM4C129_RAM_GLOBAL_vars/Debug/TM4C129_RAM_GLOBAL_vars.out
    
    Elf文件类型为EXEC (可执行文件)
    入口点0x2万d47
    有4个程序标头,从offset 7.8032万
    
    程序标头:
    类型 偏移VirtAddr PhysAddr FileSiz MemSiz Flg对齐
    负载 0x0.0034万 0x0万 0x0万 0x0.0208万 0x0.0208万 R 0x4
    加载 0x0.0023万c 0x2000万 0x2000万 0x0.108万 0x0.108万 R E 0x4
    负载 0x0012bc 0x2000.108万 0x2000.108万 0x0万 0x0.02万 RW 0x4
    负载 0x0012bc 0x2000.128万 0x2000.128万 0x000a0 0x0.012万 RW 0x4
    
    段到段映射:
    段段段...
    00 intvecs .init_array
    01 text .const
    02 堆栈
    03. 数据.bss 

    使用CCS 7.2 调试器下载程序时,Segger J-Link控制面板报告以下内存写入:

    T1410 5175:057 JLINK_WriteMem(0x0万000000,0万,0x0208字节,...) 数据:80 12 00 20 47 0D 00 20 ... -闪存
    T1410 5175:058 JLINK_WriteMem(0x2000万, 0x1080字节,...) -数据:0E B5 02 92 01 91 00 90 ...
    T1410 5175:211 JLINK_WriteMem (0x2000.128万,0x00A0字节...) 数据:01 00 00 02 00 00 00 ...
    

    使用IAR调试器下载程序时,Segger J-Link控制面板报告以下内存写入:

    T1B9万:435 JLINK_WriteMem(0x0万,0x0208字节,...) 数据:80 12 00 20 47 0D 00 20 ... -闪存
    T1B9万:435 JLINK_WriteMem(0x2000万, 0x13A0 bytes,...) -数据:0E B5 02 92 01 91 00 90 ... 

    比较ELF程序标头和写入目标的内存可以看出:

    a) IAR调试器正在正确写入MemSiz字段指定的内存区域大小,因此该字段对.bss段进行零初始化。

    B) CCS 7.2 调试器错误地只写入“FileSiz”字段指定的内存区域大小,因此不能对“MemSiz”字段大于“FileSiz”字段的任何内存区域进行零初始化。

    使用的示例附于 e2e.ti.com/.../TM4C129_5F00_RAM_5F00_global_5F00_vars.zip

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

    Chester Gillon 说:
    b) CCS 7.2 调试器错误地只写入FileSiz字段指定的内存区域大小, 因此,不会对MemSiz字段大于FileSiz字段的任何内存区域进行零初始化。

    我还测试了CCS 6.01 和CCS 6.2 ,它们的行为方式与CCS 7.2 相同。

    对于使用--ram_model的程序,一个变通方法是在链接程序命令文件中为包含未初始化变量的部分显式填充零。 例如,对于C66示例程序:

    远 > OCMC_RAM1,Fill = 0 

    此变通方法不会更改目标上的内存使用情况,但ELF .OUT文件的大小会随未初始化部分的大小而增加。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢Chester的工作。 此时,它掌握在TI手中,他们需要解决。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好,TI有人在家吗?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我认为这与未解决的问题SDSCM4.2973万有关
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我认为这与未解决的问题SDSCM4.2973万[/QUOT] SDSCM4.2973万是在5年半前提出的,但针对的是“TMS470代码生成工具”产品,即使问题似乎在CCS加载器中。

    这是缺陷尚未修复的原因吗?

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

    当CCS调试器的加载程序不能按照ELF规范进行零初始化的问题最初出现在几年前时,加载程序被更改为按照规范所说的那样。  这种更改产生了意外后果,导致某些客户的性能严重下降。 决定保留ELF标准行为,但不作为默认行为。 这种感觉是,很少有情况会依赖调试器对嵌入式程序的加载行为,因为生成的软件可能无法在实时系统中工作。

    虽然可以通过GEL启用非默认零填充行为。  在适当的Gel回调(例如启动)中执行"GEL_EnableZeroFill(1)"将启用它。

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

    可以通过GEL启用非默认零填充行为。  在适当的Gel回调(例如启动)中执行"GEL_EnableZeroFill(1)"将启用它

    感谢您的解释。 我确认它与CCS 7.2 ,0.0.0013万 ,Segger J-Link和TM4C1294NCPDT组合配合使用。