【问题标题】:ARMCC linker: creating a non-initialised regionARMCC 链接器:创建一个未初始化的区域
【发布时间】:2019-03-06 15:10:05
【问题描述】:

我正在尝试让 ARMCC 链接器将变量放入未初始化的 RAM 区域(因为我需要它们在重置后仍然存在),但失败了。我在分散链接文件中创建的区域指定了UNINIT,并且在我的__attribute__ 调用中,我指定这是zero_init RAM(否则我知道ARM 链接器认为它是Data无论你说什么,RAM 和零初始化它)。对于.map 文件下方的我的测试代码,显示链接器正在将我的测试变量放入正确的区域:

Execution Region RW_IRAM1 (Base: 0x200032ac, Size: 0x00000004, Max: 0x00000400, ABSOLUTE, UNINIT)
Base Addr    Size         Type   Attr      Idx    E Section Name  Object
0x200032ac   0x00000004   Zero   RW         8    .bss.noinit      main.o

还有这个测试代码:

#include "mbed.h"

// An unsigned int in an uninitialised RAM area
__attribute__ ((section(".bss.noinit"), zero_init))
unsigned int gRetained;

// Entry point
int main()
{
    printf("Retained RAM variable is %d.\n", gRetained);
    gRetained++;
    printf("Retained RAM variable incremented to %d.\n", gRetained);
    printf("Resetting...\n");
    wait_ms(1000);
    NVIC_SystemReset();
}

...我得到的输出是:

Retained RAM variable is 0.
Retained RAM variable incremented to 1.
Resetting...
Retained RAM variable is 0.
Retained RAM variable incremented to 1.
Resetting...
Retained RAM variable is 0.
...

谁能发现我做错了什么?

这是我的完整分散链接文件,其中RW_IRAM1 是我正在谈论的区域:

#! armcc -E

/* Default to no softdevice */
#if !defined(MBED_APP_START)
  #define MBED_APP_START 0x0
#endif

#if !defined(MBED_APP_SIZE)
  #define MBED_APP_SIZE 0x80000
#endif

/* Physical RAM */
#define MBED_RAM_PHYSICAL_START 0x20000000
#define MBED_RAM_PHYSICAL_SIZE 0x10000

/* Reserved areas */
#define MBED_RAM_SOFT_DEVICE_SIZE 0x31d0
#define MBED_RAM_UNINIT_AREA_SIZE 1024

/* If app_start is 0, do not set aside space for the softdevice */
#if MBED_APP_START == 0
  #define MBED_RAM_START  MBED_RAM_PHYSICAL_START
  #define MBED_RAM_SIZE   MBED_RAM_PHYSICAL_SIZE
#else
  #define MBED_RAM_START  (MBED_RAM_PHYSICAL_START + MBED_RAM_SOFT_DEVICE_SIZE)
  #define MBED_RAM_SIZE   (MBED_RAM_PHYSICAL_SIZE - MBED_RAM_SOFT_DEVICE_SIZE)
#endif

#define MBED_RAM0_START MBED_RAM_START
#define MBED_RAM0_SIZE  0xDC
#define MBED_RAM1_START (MBED_RAM0_START + MBED_RAM0_SIZE)
#define MBED_RAM1_SIZE  MBED_RAM_UNINIT_AREA_SIZE
#define MBED_RAM2_START (MBED_RAM1_START + MBED_RAM1_SIZE)
#define MBED_RAM2_SIZE  (MBED_RAM_SIZE - MBED_RAM0_SIZE - MBED_RAM1_SIZE)

LR_IROM1 MBED_APP_START MBED_APP_SIZE {
  ER_IROM1 MBED_APP_START MBED_APP_SIZE {
    *.o (RESET, +First)
    *(InRoot$$Sections) 
    .ANY (+RO)
  }

  RW_IRAM0 MBED_RAM0_START UNINIT MBED_RAM0_SIZE { ;no init section
    *(*nvictable)
  }
  RW_IRAM1 MBED_RAM1_START UNINIT MBED_RAM1_SIZE { ;no init section
    *(*noinit)
  }
  RW_IRAM2 MBED_RAM2_START MBED_RAM2_SIZE {
    .ANY (+RW +ZI)
  }
}

仅供参考,这是在具有 64 KB RAM 的 Nordic NRF52832 芯片上,我碰巧正在使用 mbed-os 构建,但我不认为这应该与问题有关。 ARMCC 版本是 5.06 update 6 (build 750)。

【问题讨论】:

    标签: linker-scripts armcc


    【解决方案1】:

    嗯,ARM 工具支持已经确认我的链接器配置是正确的,并检查了我的 ELF 文件以确认没有任何东西会静态覆盖我的 noinit 区域。

    问题似乎是,在 NRF52832 上有一个 BLE 堆栈位于内存中,即使我从未激活 BLE,mbed-os 中的某处也在 MBED_RAM1_START 写入了几 KB 的 BLE 配置数据,假设它拥有那个空间。所以解决方法是像 GCC 和 IAR 链接器文件一般做的那样,将 noinit 区域放置在通常的 RAM 区域之后。问题是我不知道如何使用 ARM 工具来做到这一点,因为它们没有在链接器文件中单独识别堆区域。哼哼。

    无论如何,重点是您在上面看到的配置确实有效,并且它是房间里的一头蓝色大象在这个 RAM 上蹂躏。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-05-23
      • 2018-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多