我正在尝试理解初始化代码如何与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堆栈架构的解释都会很棒。
答案 0 :(得分:5)
您将从__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字节会相当奢侈!此外,如果您正在使用分散加载文件,则只需重新实现它。