You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

STM32H7用链接脚本拆分.bss至不同RAM时符号分配异常排查

STM32H7 GCC链接脚本段迁移异常排查

问题背景

我用STM32H730VBHx芯片搭配GCC工具链开发C++程序,最近代码量上涨导致.bss段塞不下DTCMRAM,打算把CANOpen目录下文件的.bss和.COMMON段迁移到RAM_D1。之前的链接脚本一直正常,改完后却出现异常。

异常现象

  • 本该迁移到RAM_D1的CANOpen单例canOpen仍留在DTCMRAM
  • 原本该留在DTCMRAM的非CANOpen目录的ioHandler被移到了RAM_D1

相关代码示例

CANOpen单例定义(canOpen.hpp)

/**
 * @brief gets the Instance of this singleton class
 * @return reference to the object
 *
 */
static CANopen& getInstance(){
    static CANopen canOpen;

    return canOpen;

}

IoHandler单例定义(IoDirect.hpp)

/**
 * @brief gets the Instance of this singleton class
 * @return reference to the object
 */
static IoHandler& getInstance(){
    static IoHandler ioHandler;
    return ioHandler;
}

疑问

该异常可能的原因是什么?是否与新增的bss_start = _sbss_heap_D1RAM;语句有关?

可能的原因分析

  • 链接脚本匹配顺序或规则错误
    若CANOpen文件的段匹配规则位置不当,比如全局的*(.bss)放在CANOpen专属规则前,会优先把所有.bss符号分配到默认的DTCMRAM,后续专属规则直接失效;反之若全局匹配在后面,会覆盖前面的专属规则,把不该迁移的符号也弄到RAM_D1。另外如果匹配规则未精准命中CANOpen目录的目标文件,CANOpen的符号自然不会被分到RAM_D1。
  • 静态局部变量的段归属特性
    GCC对C++函数内的静态局部变量,默认会放到.bss(未初始化)或.data(有初始化)段,但这类变量的符号名会带有函数前缀,比如_ZN7CANopen11getInstanceEvE9canOpen,若链接脚本只按文件名匹配段,未针对这类符号做处理,就会匹配失败,导致canOpen留在原段。
  • 新增语句的干扰
    新增的bss_start = _sbss_heap_D1RAM;若打乱了链接脚本中内存区域的地址顺序或段初始化逻辑,比如原本bss_start标记DTCMRAM内.bss段的起始,改成指向RAM_D1起始后,链接器可能会把所有未匹配到专属规则的.bss符号都放到RAM_D1,而canOpen因未被匹配到,就留在了DTCMRAM。
  • COMMON段处理不到位
    仅处理.bss段迁移但未正确配置.COMMON段规则的话,COMMON段的全局变量会干扰整体段分配逻辑,导致符号归属混乱。

内容的提问来源于stack exchange,提问作者chat_de_schroedinger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 00:06:25