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.

[参考译文] CCS/TM4C1294NCPDT:具有 GCC 的 CCS V7:堆栈问题

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/588189/ccs-tm4c1294ncpdt-ccs-v7-with-gcc-stack-issues

器件型号:TM4C1294NCPDT

工具/软件:Code Composer Studio

您好!

我很难发现堆栈在默认情况下仅为128个字、不是8字节对齐且根本不位于 RAMTOP。 TI 人为什么选择这种奇怪的布局?

根据我对堆栈的理解:

应该是合理的大(不是128个字)。 可能1/4的 RAM 将是一个良好的开端

-应该在8字节边界上(它在 ARM ABI 规范中的某处写入、如果它不是8字节对齐、它会中断 C 库中的浮点内容、这是很难找到的)

-不应位于我的变量中间的 BSS 内部、而应位于 RAMTOP (堆栈根据我的理解向下增长)。 这会产生一种有趣的效果、根据堆栈前面偶然出现的变量数量、对齐移位、打破8字节对齐规则和浮点运算会在随机基础上工作或不工作(也是很难找到的方法)

-应使用链接器脚本中定义的段正确初始化(从我现在看到的脚本完全被忽略、堆栈指针指向 pui32Stack、它是 BSS 中的一个变量

我不确定我们是否是这样创建了两个堆栈,不知道 libc 实际上是在哪里期望堆栈。 我假设 libc 使用链接器脚本中的引用、但我们在其他位置设置栈

有人能解释一下为什么以这种方式实施? 我从未在任何其他 ARM 平台(ST、NXP)上看到过它。 我仍然遇到神秘的崩溃、我将其归咎于奇怪的堆栈管理。

我将启动代码更改为"static uint32_t __attribute__(aligned (0x8))) pui32stack[32768];"以解决上述问题、但仍会崩溃。

Markus

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

    很抱歉您遇到问题。 您对堆叠的一些担忧是"在发动机罩下"处理的。 让我来解释一下正在发生的情况、或许还可以建议一些方法来定制堆栈、从而提高效率。

    对于我们的许多示例项目、保留的堆栈空间非常小。 可以通过右键点击工程名称并 选择"Show Build Settings..."来更改堆栈的大小。 然后 展开"CCSBuild"->"ARM Linker"->"Basic Options"、您可以设置堆栈大小。

    您需要确保栈与8字节边界对齐。 实际强制在 boot.asm 中的初始化代码中执行该操作:

    ;*------------------------------------------------
    ;*如果是 EABI,则将堆栈对齐到64位。
    ;*------------------------------------------------
    .if __TI_EABI_ASSEMOV
    r7,sp
    MOVr0,#0x07
    BICS r7,r0 ;清除高3位以进行64位对齐。
    MOVsp、r7
    .endif
    

    我们大多数项目的链接命令文件对于栈的放置没有限制、除非它位于 RAM 中。 您更喜欢堆栈位于 RAM 的顶部(我假定的最高地址)、我更喜欢它位于 RAM 中的最低地址。 我之所以喜欢这种方法、是因为正如您正确指出的、堆栈向下增长(朝向较低的地址)、如果我获得堆栈溢出、而不是破坏 RAM 中的某些变量、我将在地址0x1FFFFFFx 处获得精确的数据中止。 这很容易让我认识到需要更多的堆栈空间。 只有当我没有在 RAM 开头需要矢量表的引导加载程序时、我才能执行此操作。 通过对链接命令文件进行以下修改、我可以强制链接器将我的堆栈置于 RAM 的底部:

    部分
    {
    .intvecs:> app_base
    .text:> FLASH
    .const:> FLASH
    .cinit:>闪存
    .pinit:> FLASH
    init_array:> FLASH
    
    .stack:> RAM_base
    .data :> SRAM
    .bss:> SRAM
    .sysmem:> SRAM
    }
    
    __STACK_TOP =__STACK + 256;
    

    我不喜欢的一点是链接命令文件末尾的"__stack_top"定义。 该定义用于定义要放置在闪存位置0x0000000处的值。 该值在器件复位时加载到 SP 中。 请注意、它们对堆栈大小进行了硬编码、在我的示例中为"256"。 我更希望它写为:

    _stack_top =_stack_end;
    

    现在、这会强制初始堆栈大小与上面显示的"工程选项"页面中定义的大小相同。 但是、链接命令文件中的硬编码初始大小在"boot.asm"中被覆盖、并且栈被设置为项目选项中指定的大小。 如果在器件未复位的情况下重新启动代码、则可以正确初始化堆栈。

    ;*--------------------------------------------------
    ;*初始化用户模式堆栈
    ;*--------------------------------------------------
    .if __TI_Ave_embedded_constants
    .thumb
    MOVWr0、__stack
    MOVTr0、__stack
    MOVsp、r0
    MOVWr0、__stack_size
    MOVTr0、 __STACK_SIZE
    .thumb
    .else;__TI_evee_embedded_ldr 常量
    R0、c_stack
    MOVsp、r0
    LDR r0、c_stack_size
    .endif;__TI_deve_embedded_constants
    ADDsp、r0
    
    

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

    [引用 user="Bob Crosby">Stack 的大小可以通过右键单击项目名称并 选择"Show Build Settings...(显示构建设置...)"来更改。 然后 展开"CCSBuild"->"ARM Linker"->"Basic Options"、您可以设置堆栈大小。Bob、堆栈大小的设置适用于 TI ARM 编译器。 而我认为 Markus 所询问的 GCC ARM 编译器具有不同的 CCS 工程属性和不同的启动代码。

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

    [quote user="Markus Rudolf">有人能解释一下为什么以这种方式实现它?过去、我发现 CCS 提供的链接器脚本、并且*_startup_ccs_gcc.c 启动文件没有为 GCC 运行时库提供完整的环境。

    在 CCS GNU C 编译器和链接器设置中 、我尝试解释 CCS 6.1.x 为 GCC ARM 编译器提供的链接器脚本和启动文件的一些问题、以及建议的修复。 我尚未检查 CCS 7是否修复了先前报告的任何问题、因此看起来我需要再次检查。

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

    您完全正确。 感谢您的观看。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢您的链接。 您似乎是少数几个知道自己在做什么的人之一。 我将对此进行研究。 从第一印象看、CCS V7几乎没有改进、甚至没有改进。 我的印象是、TI 并未在 CCS 中对整个 GCC 支持投入太多精力。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    感谢您对它的任何考虑。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我认为无法在8字节边界上对齐的问题是,在 GCC 的启动文件中,我们缺少一条线,用于将数组 pui32stack[128]标识为属于".stack"部分

    //
    //
    //为系统堆栈保留空间。
    ////
    *****************
    __attribute__((section (".stack"))
    )静态 uint32_t pui32stack[128];
    

    当前的“xxx_startup_ccs_gcc.c”文件中缺少“__attribute__((section(".stack"))”行。 我正在研究如何纠正这种情况。