硬件: STM32F1系列
软件环境:Keil 4.54
注:本文中提到的RTOS以RT-Thread为例,不涵盖所有RTOS的情况
在Keil MDK中新建工程时会根据所选的device自动生成启动代码文件startup.s,该文件的作用可根据其头部的注释看出
;* - Set the initial SP
;* - Set the initial PC == Reset_Handler
;* - Set the vector table entries with the exceptions ISR address
;* - Configure the clock system
;* - Branches to __main in the C library (which eventually
;* calls main()).
;* After Reset the CortexM3 processor is in Thread mode,
;* priority is Privileged, and the Stack is set to Main.
在startup.s中,完成了堆栈大小和中断向量表的设置。默认的栈大小为400字节,堆大小为200字节,可自行更改。这个栈在bare-metal系统中为全局所使用,在带RTOS的系统中被操作系统内核和中断所使用,如果无多层函数嵌套调用,通常是够用的。堆在使用malloc()的时候会被用到。堆栈的设置必须用汇编语言完成,因为C语言通常会用到函数,而函数调用是依赖于堆栈的。关于startup.s的详细分析请参考004:STM32启动文件详解及SystemInit函数分析一文
系统上电后,默认从地址为0的地方开始执行。在STM32中,若根据boot引脚选择从主闪存存储器启动,则主闪存存储器被映射到启动空间(0x0000 0000),但仍然能够在它原有的地址(0x0800 0000)访问它。0x08000000开始的一段区域存放的是中断向量表(即startup.s中__Vectors开始的部分)
; Vector Table Mapped to Address 0 at Reset AREA RESET, DATA, READONLY EXPORT __Vectors EXPORT __Vectors_End EXPORT __Vectors_Size __Vectors DCD __initial_sp ; Top of Stack DCD Reset_Handler ; Reset Handler先是执行__initial_sp设置主堆栈指针MSP(相关概念请参考宋岩翻译的《Cortex-M3权威指南》),而后执行复位操作Reset_Handler
Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT __main IMPORT SystemInit LDR R0, =SystemInit BLX R0 LDR R0, =__main BX R0 ENDPReset_Handler中首先执行SystemInit()函数(在system_stm32f10x.c文件中定义),该函数主要完成了RCC时钟的设置。接着执行__main()处的代码。在Keil IDE的工程窗口中,是无法搜索到__main()的定义的,但在汇编代码和工程map文件中可以找到它的身影
__main 0x08000121 Thumb Code 0 entry.o(.ARM.Collect$$$$00000000)
推测应该是在entry.c文件中,而entry.c文件应该是在Keil自带的library里。
参考MDK __main()代码执行过程分析一文,__main()中主要通过
1. __scatterload()把RW/RO输出段从装载域地址复制到运行域地址,并完成ZI运行域的初始化工作。
2. __rt_entry()初始化堆栈,完成库函数的初始化,最后自动跳转向main()函数。其中__user_initial_stackheap()是在startup.s中定义的
EXPORT __user_initial_stackheap __user_initial_stackheap LDR R0, = Heap_Mem LDR R1, =(Stack_Mem + Stack_Size) LDR R2, = (Heap_Mem + Heap_Size) LDR R3, = Stack_Mem BX LR
根据AAPCS的规定,栈任何时候都得4字节对齐,在调用入口得8字节对齐。对于带RTOS的系统,该函数根据
AREA STACK, NOINIT, READWRITE, ALIGN=3 AREA HEAP, NOINIT, READWRITE, ALIGN=3 PRESERVE8保证了主堆栈指针MSP是遵守规定的,而线程堆栈指针PSP全靠自己来保证每次进入C世界时是8字节对齐,通常的做法是在程序中使用__attribute__((aligned(8)))来告知编译器在分配空间时采用8字节对齐。在发生中断时,如果当前正在使用的栈指针不是8字节对齐,则先把SP-4,调整为8字节对齐,参考cortex-m3 栈的8字节对齐一文
相关推荐
#### 二、STM32启动过程分析 STM32系列微控制器基于ARM Cortex-M3内核设计,与前代产品如ARM7/ARM9相比,具有更先进的启动机制。ARM7/ARM9内核在复位后默认从地址0x000000开始执行复位中断服务程序,而Cortex-M3...
STM32启动代码分析涉及了微控制器启动过程中的关键步骤,其中包含了初始化堆栈、设置中断向量表、配置存储区以及进行系统时钟设置等重要环节。为了深入理解这些概念,首先需要了解嵌入式系统中启动代码的角色和意义...
1. **启动过程概述** STM32在上电或复位后,会执行存储在Flash中的启动代码。启动代码是程序运行的第一步,负责初始化系统硬件环境,包括时钟配置、内存映射、堆栈设置等,以便为后续的应用程序提供稳定的工作平台...
STM32是一款广泛应用于嵌入式系统的微控制器,其启动过程是理解其工作原理的关键部分之一。本文将详细解析STM32启动代码的相关知识点,帮助读者深入理解STM32的启动机制。 #### 二、启动加载器(Bootloader)概念 ...
详细解释了32的启动过程 如程序清单一,STM32的启动代码一共224行,使用了汇编语言编写,这其中的主要原因下文将会给出交代。现在从第一行开始分析: ? 第1行:定义是否使用外部SRAM,为1则使用,为0则表示不使用。...
本文通过对 STM32 微控制器的启动过程的分析,帮助读者更好地理解 STM32 微控制器的启动过程和初始化操作,并掌握 STM32 微控制器的开发技术。 在这个过程中,我们还可以看到,STM32 微控制器的启动过程与 ARM7/ARM...
STM32的启动代码是其正常工作的基石,通过对`stm32f10x_vector.s`文件的详细分析,我们可以深入了解STM32的内存管理、异常处理机制及启动过程。这对于嵌入式系统的开发者来说是非常宝贵的资源。掌握了这些知识后,...
本文将深入探讨STM32启动过程,分析启动代码的各个阶段及其功能,帮助开发者更好地理解STM32的工作原理。 首先,STM32启动流程通常包括以下步骤: 1. **上电复位(Power-on Reset, POR)**:当系统电源接通时,STM...
STM32 Logic STM32 逻辑分析仪是一种利用STM32微控制器开发的硬件设备,用于捕获并分析数字信号。这种逻辑分析仪通常由软件和硬件两部分组成,能够帮助开发者在嵌入式系统中调试和理解数字信号的传输过程。在本项目...
### STM32启动过程深度解析 #### 引言 在嵌入式系统开发领域,STM32微控制器凭借其高性能与灵活性,成为诸多项目的核心组件。深入理解STM32的启动过程,对于优化代码效率、确保系统稳定运行具有重要意义。本文将...
### STM32F103程序运行启动过程解析 #### 一、STM32启动配置与...通过以上对启动过程的详细分析,我们可以了解到STM32F103启动过程中涉及的重要概念和技术细节,这对于深入理解和掌握该微控制器的工作原理至关重要。
接下来,我们将基于STM32的标准启动文件`stm32f10x_vector.s`来详细分析STM32的启动过程。 ##### 2.3.1 堆栈与堆空间初始化 启动文件首先定义了栈(Stack)和堆(Heap)的空间大小及起始地址: 1. `Stack_SizeEQU...
STM32F1与STM32F0在启动配置上存在差异,主要体现在启动加载地址、启动选择方式等方面。开发者需根据新芯片的特点重新配置启动参数,确保系统能够正确加载程序。 #### 3. 外设迁移 外设是实现微控制器功能的关键...
**基于STM32烟雾传感器...项目实施过程中涉及STM32微控制器的配置、ADC的使用以及烟雾传感器的接口设计等多个技术环节,是嵌入式系统设计中的典型应用案例。通过深入理解和实践,可以提升对STM32及传感器应用的掌握。
通过对STM32的堆栈内存进行深入分析,我们可以更好地理解其内存管理机制,并在实际开发过程中有效地避免内存相关问题的发生。掌握STM32的内存布局不仅有助于编写高效的程序,还能提高程序的稳定性和可靠性。
这份文件定义了STM32启动过程中的核心组件和行为,下面我们详细分析一下其中的关键部分: 1. **内存布局**: - `DATA_IN_ExtSRAM EQU 0`:此行定义了一个常量`DATA_IN_ExtSRAM`,值为0,用于指示外部SRAM的起始...