STM32启动代码详细分析
最近需要学习iap的功能,因此离不开stm32的启动代码的分析,以前看了很多遍,都看不懂,读书百遍,其义自见,因此我有看了一遍,下面的文章,挺好的,因此转载:
在上电复位后,我们都知道会先运行启动代码,但是启动代码到底使干什么用的呢?下面小弟给大家一一列出来。
1、初始化堆栈指针
2、初始化 PC 指针
3、初始化中断向量表
4、配置系统时钟
5、调用 C 库函数_main 初始化用户堆栈
我们根据这以上的几个步骤一一进行详细的解析:
1、栈的内存分配
这段代码的意思是,开辟了一个栈,这个栈的大小是0x00000400也就是1KB的大小,名字为STACK,不初始化,可读可写,2^3=8字节对齐。
那么问题来了,那这个栈到底使干什么的呢?小弟相信大家在学习C语言的时候应该也是知道了,栈区保存的是局部变量,只是当时并没有深入研究它的大小问题。那在这里小弟给大家详细讲解一下栈的作用:
1、局部变量
2、函数调用
3、函数形参
以上的这三种情况的开销都是使用我们的栈区的资源的。所以啊!这里小弟给个位提个醒,千万不要把栈区当成无止境大小的
哦!STM32可不比我们的电脑,没有那么多的空间可以给大伙挥霍,如果我们定义的局部变量过大可是会莫名其妙报错的。
温馨提示:请不要在写程序时,过度使用局部变量,会造成栈的益处,从而导致编译报错,如果在特殊情况下真的需要很大的栈区空间,只需来这里进行栈区大小的修改即可。
那么小弟再来给这个程序段里的汇编指令做一个详细的介绍
Stack_Size EQU 0x00000400
EQU:宏定义的伪指令,相当于等于,类似与 C 中的 define。
这句话的意思是,定义一个宏名Stack_Size这个宏代表0x00000400的意思,用我们C语言来表示就是
#define Stack_Size 0x00000400
AREA STACK, NOINIT, READWRITE, ALIGN=3
AREA:告诉汇编器汇编一个新的代码段或者数据段。
STACK:表示段名
NOINIT:表示不初始化
READWRITE:表示可读可写
ALIGN=n:表示按照 2^n字节对齐
这里小弟就不多说了,解释已经很详细了,小哥哥小姐姐们自己组合起来吧
Stack_Mem SPACE Stack_Size
SPACE:用于分配一定大小的内存空间,单位为字节。
这句话的意思是,分配一个内存空间,这个内存空间的大小为Stack_Size,也就是我们刚才宏定义的0x00000400
然后最后标号__initial_sp 紧挨着 SPACE 语句放置,表示栈的结束地址。也就是栈顶的地址。
温馨提示:栈的生长是由高地址向低地址生长的。
2、堆的内存分配
这段代码的意思是,开辟堆的大小为0x00000200也就是512B的大小,名字为HEAP,不初始化,8字节对齐。
在之前我们一直认为的是,全局变量,静态变量都分配在堆区中,这里是不正确的,我们的全局变量和静态变量,并不是直接
分配在堆中,这里的堆只有malloc函数分配的内存,会在这里进行分配,而静态变量和局部变量都是在SRAM中分配,这也就是为什么我们全局变量可以定义一个大于512B大小的空间了。
温馨提示:如果使用了malloc函数一定要注意这个堆咯!不可以大于512B呢!当然这里也可以进行修改。
那咱们再来一条一条语句进行分析吧!
Heap_Size EQU 0x00000200
这里我们就不多说了这条代码和上面那条是一个意思
AREA HEAP, NOINIT, READWRITE, ALIGN=3
这里也和上面差不多,唯一改变的就是段名是HEAP而不是STACK了
__heap_base
在SPACE前出现这条代码代表的是堆的起始地址
Heap_Mem SPACE Heap_Size
这里是分配一个0X00000200大小的空间
__heap_limit
在SPACE后出现这条代码代表的是堆的结束地址
PRESERVE8
指定当前文件的堆栈按照 8 字节对齐
THUMB
表示后面指令兼容 THUMB 指令。THUBM 是 ARM 以前的指令集,16bit,现在 Cortex-M 系列的都使用 THUMB-2 指令集,THUMB-2 是 32 位的,兼容 16 位和 32 位的指令。
3、向量表
这段代码的意思是,定义了一个数据短,名字叫RESET,只可读。
那么这里问题来了,什么是向量表呢!在这里,这个向量表示为了决定中断服务函数的入口的,每一个向量表都是4个字节,
向量表决定了入口的偏移地址。
AREA RESET, DATA, READONLY
这句话的意思是定义了一个代码段RESET,只可读
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size
这三句话都是同一个意思,相当于C语言中的EXPORT可以被外部文件所引用
向量表如下
...........................省略部分.................................
这里呢,就是我们的中断向量表了,我们可以发现,它是从栈区中开始加载的,从栈顶开始,
__Vectors 代表向量起始地址
__Vectors_End 代表向量结束地址
DCD:分配一个或者多个以字为单位的内存,以四字节对齐,并要求初始化这些内存。在向量表中,DCD 分配了一堆内存,并且以 ESR 的入口地址初始化它们
Reset_Handler
NMI_Handler
HardFault_Handler
MemManage_Handler
BusFault_Handler
UsageFault_Handler
这些都是地址,我们的知道,函数名就是函数的地址,所以我们的中断服务函数必须使用这些作为函数名,否则无法正确进入中断服务函数。
__Vectors_Size EQU __Vectors_End - __Vectors
通过这句话我们知道结束地址-起始地址,自然就是向量表的大小了。
好的,个位小哥哥小姐姐,今天的课就上到这里了,剩下的部分我们下回分解。
STM32启动代码详细分析的更多相关文章
- iar stm32 启动代码片段分析
今天查看了 iar 上面的启动文件,好奇堆栈指针到底是什么时候赋值的,所以就仔细的阅读了代码和相关手册,找到了答案. 首先,芯片启动后,会从ROM的首地址处进行执行,那么我们从 linker 里面找找 ...
- STM32启动代码分析 IAR 比较好
stm32启动代码分析 (2012-06-12 09:43:31) 转载▼ 最近开始使用ST的stm32w108芯片(也是一款zigbee芯片).开始看他的启动代码看的晕晕呼呼呼的. 还好在c ...
- STM32启动代码分析
STM32启动文件简单分析(STM32F10x.s适用范围)定时器, 型号, 名字在<<STM32不完全手册里面>>,我们所有的例程都采用了一个叫STM32F10x.s的启动文 ...
- STM32启动代码分析及其汇编学习-ARM
STM32 启动代码 Author By YuCloud 边看启动文件边学汇编 汇编 see ARM: Assembler User Guide see: https://blog.csdn.net/ ...
- 海思uboot启动流程详细分析(转)
海思uboot启动流程详细分析(一) 海思uboot启动流程详细分析(二) 海思uboot启动流程详细分析(三)
- 海思uboot启动流程详细分析(三)【转】
1. 前言 书接上文(u-boot启动流程分析(二)_平台相关部分),本文介绍u-boot启动流程中和具体版型(board)有关的部分,也即board_init_f/board_init_r所代表的. ...
- STM32 启动代码 bootloader
什么是启动代码? 启动代码是系统上电或者复位后运行的第一段代码,是进入C 语言的main 函数之前需要执行的那段汇编代码.STM32的启动代码在startup_stm32f10x_hd.s 启 ...
- STM32向量表详细分析
预备知识: DCD指令:用于分配一片连续的字存储单元(32bit),并将表达式的值初始化给该字存储单元,类似于C中定义数组并初始化.比如: DCD 0 的意思是:分配一个字存储单元,并将该单元初始化为 ...
- lk启动流程详细分析
转载请注明来源:cuixiaolei的技术博客 这篇文章是lk启动流程分析(以高通为例),将会详细介绍下面的内容: 1).正常开机引导流程 2).recovery引导流程 3).fastboot引导流 ...
随机推荐
- SpringBoot加载自定义yml文件
自定义配置文件(跟SpringBoot的application.yml同一目录下): nlu-parse-rule: title: "NLU响应结果解析规则" desc: &quo ...
- LeetCode 5108. Encode Number - Java - 2进制
题目链接:https://leetcode-cn.com/problems/encode-number/ Given a non-negative integer num, Return its en ...
- Function Evaluation
Author: Leisureeen Time Limit: 100ms Memory Limit: 65535KB Code Size Limit: 16 KB 64-bit integer IO ...
- gRPC-拦截器简单使用
概述 gRPC作为通用RPC框架,内置了拦截器功能.包括服务器端的拦截器和客户端拦截器,使用上大同小异.主要作用是在rpc调用的前后进行额外处理. 从客户端角度讲,可以在请求发起前,截取到请求参数并修 ...
- MySQL恩恩怨怨
数据库基础 Windows安装MySQL Mac安装MySQL Linux安装MySQL MySQL存储引擎概述 MySQL表操作 MySQL支持的数据类型 MySQL表的完整性约束 MySQL记录操 ...
- ubuntu 使用阿里云镜像源快速搭建kubernetes 1.15.2集群
一.概述 搭建k8s集群时,需要访问google,下载相关镜像以及安装软件,非常麻烦. 正好阿里云提供了k8s的更新源,国内用户就可以直接使用了. 二.环境介绍 操作系统 主机名 IP地址 功能 配置 ...
- emmet css 缩写
css 缩写 对于CSS语法,Emmet有许多用于属性的预定义代码段.例如,您可以扩展 m 缩写以获取margin: ;代码段. 要获取 margin: 10px;您可以简单地扩展m10缩写. 需要多 ...
- node-red inject节点 debug节点 switch节点
inject节点: https://blog.csdn.net/geek_monkey/article/details/80737818 debug节点: https://blog.csdn.net/ ...
- (转)Python_如何把Python脚本导出为exe程序
原文地址:https://www.cnblogs.com/robinunix/p/8426832.html 一.pyinstaller简介 Python是一个脚本语言,被解释器解释执行.它的发布方式: ...
- 强大的Grafana k8s 插件
原文参考: https://i4t.com/4152.html 参考:https://blog.csdn.net/mailjoin/article/details/81389700 插件链接:http ...