我试图了解 STM32 微 Controller 的 Keil (realview v4) 附带的初始化代码是如何工作的。具体来说,我试图了解堆栈是如何初始化的。
在 documentation在ARM的网站上,它提到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() 取代;后者的文档提供了有关您的问题的线索:
Unlike __user_initial_stackheap(), __user_setup_stackheap() works with systems where the application starts with a value of sp (r13) that is already correct, for example, Cortex-M3
[..]
Using __user_setup_stackheap() rather than __user_initial_stackheap() improves code size because there is no requirement for a temporary stack.
在 Cortex-M 上,sp 在复位时由硬件根据向量表中存储的值进行初始化,在较旧的 ARM7 和 ARM9 设备上情况并非如此,需要在软件中设置堆栈指针。在应用用户定义的堆栈之前,启动代码需要一个小堆栈供使用 - 例如,如果用户堆栈位于外部存储器中并且在存储器 Controller 初始化之前无法使用,则可能会出现这种情况。施加 88 字节限制只是因为此临时堆栈的大小尽可能小,因为它在启动后可能不会被使用。
就您的 STM32(Cortex-M 设备)而言,实际上很可能没有这样的限制,但您也许应该更新启动代码以使用较新的函数来确定。也就是说,考虑到该函数所需的行为以及其结果在寄存器中返回的事实,我建议如果您需要那么多字节,88 字节将是相当奢侈的!此外,如果您按照描述使用分散加载文件,则只需重新实现它。
关于ARM Cortex-M3 启动代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26643465/