我正在尝试但没有通过,以使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更新6(内部版本750)。
答案 0 :(得分:0)
好,ARM工具支持已确认我的链接器配置正确,并检查了我的ELF文件以确认没有任何内容会静态覆盖我的noinit区域。
问题似乎是,在NRF52832上有一个BLE堆栈位于内存中,即使我从未激活BLE,mbed-os中某处的某处也在MBED_RAM1_START写入了几KB的BLE配置数据,假设它拥有那个空间。因此,解决方法是按照GCC和IAR链接器文件的一般做法,并将noinit区域放在之后的普通RAM区域中。问题是我不知道如何使用ARM工具来执行此操作,因为它们无法在链接器文件中单独标识堆区域。哼!
无论如何,主要的一点是,您在上面看到的配置确实有效,并且房间中的一头蓝色大象正在踩此RAM。