你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

将 IAR 的 __no_init 指令移植到 GCC 编译器

[复制链接]
patch1582 提问时间:2026-5-25 09:00 / 未解决

我想将 IAR 工程移植到 STM32CubeIDE(GCC),遇到了好几个问题。其中一个问题出在下面这行代码:

pragma location=0x30024000

__no_init short rtp_rin_ni [RTP_SIZE_AR ];

我需要将 IAR 的 __no_init 指令移植到 GCC 编译器,请教怎么实现?

收藏 评论1 发布时间:2026-5-25 09:00

举报

1个回答
fafa1 回答时间:1 小时前

核心方案

GCC 方案通常分为两步:

  1. 修改链接脚本 (.ld) :定义一个特殊的、不会被初始化的内存段。
  2. 修改源代码 :使用 __attribute__ 将变量放置到该段中。

注意:GCC 的 __attribute__((section())) 只指定了变量所属的段名,其实际地址是由链接脚本决定的

第一步:修改链接脚本 (.ld)

打开你项目中的 .ld 链接脚本(通常命名为 STM32XXXXXX_FLASH.ld),修改其内容以实现精确指定地址。

修改内存区域 (MEMORY)

  1. MEMORY 块中,添加一个新的内存区域,并指定好起始地址 (ORIGIN) 和大小 (LENGTH)。 ld

    MEMORY
    {
      RAM (xrw)      : ORIGIN = 0x20000000, LENGTH = 128K
      CCMRAM (xrw)   : ORIGIN = 0x10000000, LENGTH = 64K
      /* 新增: 用于 no_init 变量的 RAM 区域 */
      MY_NOINIT (rwx) : ORIGIN = 0x30024000, LENGTH = 8K
      FLASH (rx)     : ORIGIN = 0x8000000, LENGTH = 1024K
    }
    • ORIGINLENGTH 的值需要根据你的芯片手册和需求进行修改
  2. SECTIONS 块中,为你的变量定义一个输出段,并指定放置到上面刚创建的内存区域。 ld

    SECTIONS
    {
      /* ... 其他段 ... */
    
      /* 新增: no_init 变量段,放置在 MY_NOINIT 内存区域 */
      .my_noinit (NOLOAD) :
      {
        . = ALIGN(4);
        KEEP(*(.my_noinit)) /* 收集所有 .my_noinit 段的内容 */
        . = ALIGN(4);
      } > MY_NOINIT
    
      /* ... 其他段 ... */
    }
    • (NOLOAD) 属性是关键,它告诉链接器不要在程序启动时初始化该段的内容,这与 __no_init 的作用相同。
    • 如果你需要多个变量各自指定不同的绝对地址,则需要按照这个方法,定义多个不同的内存区域和段。

    第二步:修改源代码

    完成链接脚本的修改后,回到你的 C 文件,声明变量如下:

    define RTP_SIZE_AR (128) // 根据实际情况定义数组长度

    / 使用 attribute 指定该变量放入 .my_noinit 段 / attribute((section(".my_noinit"))) volatile short rtp_rin_ni[RTP_SIZE_AR]; 同时,在定义中建议加上 volatile 关键字,防止编译器对该内存访问进行过度优化。

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版