`

STM32启动过程分析

阅读更多

硬件: STM32F1系列

软件环境:Keil 4.54

注:本文中提到的RTOS以RT-Thread为例,不涵盖所有RTOS的情况

 

在Keil MDK中新建工程时会根据所选的device自动生成启动代码文件startup.s,该文件的作用可根据其头部的注释看出

This module performs:
;* - 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
                 ENDP
 Reset_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字节对齐一文

补充:startup.s定义了中断处理函数

NMI_Handler     PROC        ;过程的开始
                EXPORT  NMI_Handler  [WEAK]
                B    .      ;原地跳转(即无限循环),
                ENDP        ;过程的结束

 其中WEAK作为若定义,意思是如果在别处也定义该symbol,在链接时用别处的地址,而stm3210x_it.c这个文件通常会进行这些中断处理函数的重新定义

 

 

分享到:
评论

相关推荐

    stm32启动过程详解

    详细解释了32的启动过程 如程序清单一,STM32的启动代码一共224行,使用了汇编语言编写,这其中的主要原因下文将会给出交代。现在从第一行开始分析: ? 第1行:定义是否使用外部SRAM,为1则使用,为0则表示不使用。...

    STM32低功耗三种方式唤醒

    整个工程包含3个源文件:STM32F10x.s、stm32f10x_it.c和main.c,其中STM32F10x.s为启动代码,所有中断 服务子程序均在stm32f10x_it.c中,其它函数则在main.c中。下面分别介绍相关的函数,具体程序清单见参考程序。 ...

    基于STM32的μCOSⅡ移植例程

    在学习的过程中,启动代码看不动,经过搜集得到了一份STM32启动代码的分析,感觉还不错,就分享了,希望会有所帮助。

    STM32单片机的入门教程总结

    根据ARM的统计,2010年全部Cortex-MMCU出货量为1.44亿片,2008年~2011年第一季度,STM32累计出货量占Cortex-MMCU出货量的45%。也就是说,两个Cortex-M微控制器中有一个就来自ST。”很多市场分析机构也ARM的强劲增长...

    基于STM32的家用智能风扇控制器设计

    以STM32作为主控制器,采用温湿度传感器、人体红外感应模块作为环境检测元件,采用TFT触控屏(或LCD显示模块结合按键)作为人机的交互设备,设计一适用于家用电风扇的风扇智能控制器。能在档位按键的控制下多档调节...

    STM32_keil_mdk启动代码发分析

    STM32 keil mdk启动代码发分析_转2010年01月29日 星期五 13:50 ;// <h> Stack Configuration ;// <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8> ;// </h> Stack_Size EQU 0x00000200 ;//定义堆栈大小 AREA ...

    STM32大棚DHT11温湿度监测

    监测装置进行监测过程,每隔一段时间系统将会进行换风装置启动;制热装置启动时,车内车外温度相差很大,每隔一段时间系统将会启动报警器装置进行提醒除霜, 启动除霜装置。通过按键实现温度湿度范围以及换风大小的...

    基于STM32的多步进电机控制系统研究

    本文在分析 P WM脉冲信号控制步进电机原理的基础上,提出了一种控制方法,可以实现多台步进电机同时启动、加速、高速、减速及 到达不同目标位置后同时制动。启动加速过程防止了 步进电机突然高速运行时失步现象的...

    mbed分析-启动过程

    mbed rtos系统启动分析,绝对纯手打,分析过程是根据程序执行流程来的,通俗易懂。本人原创!

    ARM启动流程及启动代码分析

    一、ARM的启动流程 基于ARM的芯片多数为复杂的片上系统。这种复杂系统里的多数硬件...以stm32的启动文件为例,stm32的启动文件一般都是包含在具体单片机型号的汇编文件中(.s文件),下图为启动文件的简述(description)

    直流电机调速-课程报告.pdf

    在建立好模型与计算好参数的基础上,利用Simulink对直流双闭环调速系统进行仿真,对空载启动过程、额定负载启动和负载切换进行仿真。仿真结果与理论分析一致。硬件电路以STM32F103C8T6作为控制器,包括主功率电路、...

    KEIL MDK输出map文件分析

    对一个烧录了程序的STM32开发板从启动复位到进入用户main函数的过程有了一个大概的了解,但是有很多问题感觉还是模模糊糊,因此,今天又把KEIL MDK编译、链接后生成的map文件简单分析一下,加深对链接器、嵌入式系统...

    uboot 代码重定位(位置有关码)(存储地址,运行地址,链接地址)

    1、代码启动过程简要分析 2、存储地址,运行地址,链接地址 2.1、存储地址 2.2、链接地址 2.3、运行地址 2.4、链接地址和运行地址的区别 3、位置有关码,位置无关码详细解释 4、代码重定位 4.1、重定位代码详解 1、...

    MDK main函数运行前的分析.pdf

    讲解了stm32f103运行main函数之前微控制器所做的工作。 总结启动文件的整个过程,分为如下: (1) 系统初始化,包括对中断向量表的重新映射; (2) 加载 RW 段; (3) ZI 段清零; (4) 初始化用户堆栈; ...

    MQXLite操作系统在ARM Cortex-M0+/M4上的移植研究与实现

    利用此模板在ARM Cortex-M0+/M4芯片上实现了MQXLite的移植,并从启动流程、中断系统、系统定时器及应用任务这几个方面详细介绍了移植过程。最后在KW01及CC3200两款不同内核、不同厂商的芯片上进行了MQXLite的移植...

    电子设计大赛——单主控MCU的选择.doc

    STM32F103RB 他的好处与LPC2138差不多,但是资料更多些,而且提供了一些算法库(FFT,PID),这个算法 库是很有用的,因为让你用汇编去写这个是不现实的,自己用C语言写的效率也很低,有了 这些你就可以直接调用了,而且STM32...

    【RT-Thread作品秀】基于深度学习的机器故障智能检测设备-电路方案

    实现功能本项目基于RT-Thread、STM32开发板(NUCLEO-H743ZI2做了演示版本,ART-Pi只验证调试了传感器,跑通了流程,存在模拟i2c通信效率问题)、STM32 LSM6DSOX传感器、1.12寸OLED屏,SHT31温湿度传感器(温湿度数据...

    【RT-Thread作品秀】设备运行数据分析预警系统-电路方案

    开发环境本项目采用到硬件方案是:通过ART-Pi STM32H750主板上的I2C引脚和UART以及一个普通IO口就可以实现与STEVAL-MKI197V1(LSM6DSOX)六轴传感器和STEVAL-MKI192V1(LPS22HH)气压传感器的I2C通信,与广和通L610-...

Global site tag (gtag.js) - Google Analytics