如何将堆栈对齐到 SRAM 的末尾?
How can I align stack to the end of SRAM?
我有一个带有 48kb SRAM 的 STM32F103VCT6
微控制器,最近我遇到了内存冲突:
我有一些静态变量(我们称之为 A
)位于堆中,大小为 0x7000
,我写了一些简单的函数来获取有关堆栈和堆的信息:
void check(int depth) {
char c;
char *ptr = malloc(1);
printf("stack at %p, heap at %p\n", &c, ptr);
if (depth <= 0) return;
check(depth-1);
}
所以我得到了这样的东西:
stack at 2000939b, heap at 20008fd0
stack at 20009383, heap at 20008fe0
stack at 2000936b, heap at 20008ff0
stack at 20009353, heap at 20009000
stack at 2000933b, heap at 20009010
stack at 20009323, heap at 20009020
stack at 2000930b, heap at 20009030
stack at 200092f3, heap at 20009040
stack at 200092db, heap at 20009050
stack at 200092c3, heap at 20009060
stack at 200092ab, heap at 20009070
所有静态变量(包括A
)都已经得到了他们的堆,所以堆位于0x8fd0
。看起来,最初,堆栈指针位于 0x939b
,远离 48kb (0xc000
)
当我将 A
变量大小更改为 0x4000
时,我得到了这张照片:
stack at 2000639b, heap at 20005fd0
stack at 20006383, heap at 20005fe0
stack at 2000636b, heap at 20005ff0
stack at 20006353, heap at 20006000
stack at 2000633b, heap at 20006010
stack at 20006323, heap at 20006020
stack at 2000630b, heap at 20006030
stack at 200062f3, heap at 20006040
stack at 200062db, heap at 20006050
stack at 200062c3, heap at 20006060
stack at 200062ab, heap at 20006070
因此,堆栈位置似乎不位于 SRAM 的末尾,而是依赖于用户定义的变量。
如何将堆栈对齐到 SRAM 的最末端(48kb)?
我正在使用 CooCox IDE 和 GNU Tools ARM Embedded
工具链。
谢谢!
编辑:
抱歉这里有些误会,A
不是 const,我称它为 static 只是因为关键字:
static uint8_t A[A_SIZE];
printf("A is at %p\n", &A);
这表明A
位于内存的开头:
A is at 20000c08
GNU 工具链使用目标特定的链接描述文件(通常带有 .ld 文件扩展名)。这将描述您的目标的内存布局,并且可以根据需要进行自定义。
您推断堆栈和堆位置的方式有些不确定且过于复杂。简单地查看链接器生成的映射文件输出(ld 命令行选项 -Map <mapfile>
)。
要简单得多,也完全准确。
根据定义,堆是用于动态分配的,因此隐含地不用于分配静态数据;这是你的误解。链接器将在构建时分配静态数据位置。链接描述文件可能会分配一个固定大小的堆栈,然后将所有剩余的和未保留用于其他目的的堆栈分配给堆。自定义脚本还可以为其他目的分配区域,例如 DMA 缓冲区或电池供电域。
无论哪种方式,堆栈的放置都不太可能解决您的实际问题;只是移动东西;它不会增加可用内存;任何堆栈溢出都会与其他东西发生碰撞。
我找到原因了:那是因为堆栈大小实际上是固定的,它位于堆中(如果我可以称之为堆的话)。
在文件 startup_stm32f10x*.c
中有一个部分:
/*----------Stack Configuration----------*/
#define STACK_SIZE 0x00000100 /*!< The Stack size suggest using even number */
然后是下一行:
__attribute__ ((section(".co_stack")))
unsigned long pulStack[STACK_SIZE];
我已将此值更改为 0x00000500
,一切正常。
我有一个带有 48kb SRAM 的 STM32F103VCT6
微控制器,最近我遇到了内存冲突:
我有一些静态变量(我们称之为 A
)位于堆中,大小为 0x7000
,我写了一些简单的函数来获取有关堆栈和堆的信息:
void check(int depth) {
char c;
char *ptr = malloc(1);
printf("stack at %p, heap at %p\n", &c, ptr);
if (depth <= 0) return;
check(depth-1);
}
所以我得到了这样的东西:
stack at 2000939b, heap at 20008fd0
stack at 20009383, heap at 20008fe0
stack at 2000936b, heap at 20008ff0
stack at 20009353, heap at 20009000
stack at 2000933b, heap at 20009010
stack at 20009323, heap at 20009020
stack at 2000930b, heap at 20009030
stack at 200092f3, heap at 20009040
stack at 200092db, heap at 20009050
stack at 200092c3, heap at 20009060
stack at 200092ab, heap at 20009070
所有静态变量(包括A
)都已经得到了他们的堆,所以堆位于0x8fd0
。看起来,最初,堆栈指针位于 0x939b
,远离 48kb (0xc000
)
当我将 A
变量大小更改为 0x4000
时,我得到了这张照片:
stack at 2000639b, heap at 20005fd0
stack at 20006383, heap at 20005fe0
stack at 2000636b, heap at 20005ff0
stack at 20006353, heap at 20006000
stack at 2000633b, heap at 20006010
stack at 20006323, heap at 20006020
stack at 2000630b, heap at 20006030
stack at 200062f3, heap at 20006040
stack at 200062db, heap at 20006050
stack at 200062c3, heap at 20006060
stack at 200062ab, heap at 20006070
因此,堆栈位置似乎不位于 SRAM 的末尾,而是依赖于用户定义的变量。
如何将堆栈对齐到 SRAM 的最末端(48kb)?
我正在使用 CooCox IDE 和 GNU Tools ARM Embedded
工具链。
谢谢!
编辑:
抱歉这里有些误会,A
不是 const,我称它为 static 只是因为关键字:
static uint8_t A[A_SIZE];
printf("A is at %p\n", &A);
这表明A
位于内存的开头:
A is at 20000c08
GNU 工具链使用目标特定的链接描述文件(通常带有 .ld 文件扩展名)。这将描述您的目标的内存布局,并且可以根据需要进行自定义。
您推断堆栈和堆位置的方式有些不确定且过于复杂。简单地查看链接器生成的映射文件输出(ld 命令行选项 -Map <mapfile>
)。
根据定义,堆是用于动态分配的,因此隐含地不用于分配静态数据;这是你的误解。链接器将在构建时分配静态数据位置。链接描述文件可能会分配一个固定大小的堆栈,然后将所有剩余的和未保留用于其他目的的堆栈分配给堆。自定义脚本还可以为其他目的分配区域,例如 DMA 缓冲区或电池供电域。
无论哪种方式,堆栈的放置都不太可能解决您的实际问题;只是移动东西;它不会增加可用内存;任何堆栈溢出都会与其他东西发生碰撞。
我找到原因了:那是因为堆栈大小实际上是固定的,它位于堆中(如果我可以称之为堆的话)。
在文件 startup_stm32f10x*.c
中有一个部分:
/*----------Stack Configuration----------*/
#define STACK_SIZE 0x00000100 /*!< The Stack size suggest using even number */
然后是下一行:
__attribute__ ((section(".co_stack")))
unsigned long pulStack[STACK_SIZE];
我已将此值更改为 0x00000500
,一切正常。