我试图了解Keil(realview v4)随附的STM32微控制器初始化代码的工作方式。具体来说,我试图了解如何初始化堆栈。

在ARM网站上的documentation中,它提到了startup_xxx.s中的例程之一__user_initial_stack_heap不应使用超过88个字节的堆栈。您知道这种限制来自何处吗?

看来,当重置处理程序调用System_Init时,它正在C环境中执行几个函数,我相信这意味着它正在使用某种形式的临时堆栈(它分配了一些自动变量)。但是,一旦返回并随后调用__main(即从中调用__user_initial_stack_heap的位置),所有这些堆叠项应超出范围。

那么,为什么对__user_initial_stack_heap的使用量不得超过88个字节的要求呢? __main的其余部分是否使用大量堆栈或其他内容?

关于cortex-m3堆栈体系结构(与启动顺序有关)的任何解释都将是极好的。

最佳答案

您可以从__user_initial_stackheap()文档中看到,该功能用于旧版支持,并且已被__user_setup_stackheap()取代;后者的文档为您的问题提供了线索:


与__user_initial_stackheap()不同,__ user_setup_stackheap()适用于应用程序以正确的sp(r13)值开头的系统,例如Cortex-M3

[..]

使用__user_setup_stackheap()而不是__user_initial_stackheap()可以提高代码大小,因为不需要临时堆栈。


在Cortex-M上,硬件通过复位从存储在向量表中的值初始化sp,而在较早的ARM7和ARM9设备上则不是这种情况,必须在软件中设置堆栈指针。在应用用户定义的堆栈之前,启动代码需要使用一个小的堆栈-例如,如果用户堆栈位于外部存储器中并且在初始化内存控制器之前无法使用,则可能是这种情况。施加88字节限制的原因很简单,因为此临时堆栈的大小应尽可能小,因为启动后可能未使用该临时堆栈。

就您在STM32(Cortex-M设备)中的情况而言,实际上可能没有这样的限制,但是您可以确定要使用较新的功能来更新启动代码。就是说,考虑到该函数的必要行为以及其结果在寄存器中返回的事实,我建议如果您需要那么多88字节,那就太浪费了!而且,仅在按照所述使用分散加载文件时才需要重新实现它。

关于embedded - ARM Cortex-M3启动代码,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26643465/

10-11 16:34