最近需要学习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启动代码详细分析的更多相关文章

  1. iar stm32 启动代码片段分析

    今天查看了 iar 上面的启动文件,好奇堆栈指针到底是什么时候赋值的,所以就仔细的阅读了代码和相关手册,找到了答案. 首先,芯片启动后,会从ROM的首地址处进行执行,那么我们从 linker 里面找找 ...

  2. STM32启动代码分析 IAR 比较好

    stm32启动代码分析 (2012-06-12 09:43:31) 转载▼     最近开始使用ST的stm32w108芯片(也是一款zigbee芯片).开始看他的启动代码看的晕晕呼呼呼的. 还好在c ...

  3. STM32启动代码分析

    STM32启动文件简单分析(STM32F10x.s适用范围)定时器, 型号, 名字在<<STM32不完全手册里面>>,我们所有的例程都采用了一个叫STM32F10x.s的启动文 ...

  4. STM32启动代码分析及其汇编学习-ARM

    STM32 启动代码 Author By YuCloud 边看启动文件边学汇编 汇编 see ARM: Assembler User Guide see: https://blog.csdn.net/ ...

  5. 海思uboot启动流程详细分析(转)

    海思uboot启动流程详细分析(一) 海思uboot启动流程详细分析(二) 海思uboot启动流程详细分析(三)  

  6. 海思uboot启动流程详细分析(三)【转】

    1. 前言 书接上文(u-boot启动流程分析(二)_平台相关部分),本文介绍u-boot启动流程中和具体版型(board)有关的部分,也即board_init_f/board_init_r所代表的. ...

  7. STM32 启动代码 bootloader

    什么是启动代码?     启动代码是系统上电或者复位后运行的第一段代码,是进入C 语言的main 函数之前需要执行的那段汇编代码.STM32的启动代码在startup_stm32f10x_hd.s 启 ...

  8. STM32向量表详细分析

    预备知识: DCD指令:用于分配一片连续的字存储单元(32bit),并将表达式的值初始化给该字存储单元,类似于C中定义数组并初始化.比如: DCD 0 的意思是:分配一个字存储单元,并将该单元初始化为 ...

  9. lk启动流程详细分析

    转载请注明来源:cuixiaolei的技术博客 这篇文章是lk启动流程分析(以高通为例),将会详细介绍下面的内容: 1).正常开机引导流程 2).recovery引导流程 3).fastboot引导流 ...

随机推荐

  1. SpringBoot加载自定义yml文件

    自定义配置文件(跟SpringBoot的application.yml同一目录下): nlu-parse-rule: title: "NLU响应结果解析规则" desc: &quo ...

  2. LeetCode 5108. Encode Number - Java - 2进制

    题目链接:https://leetcode-cn.com/problems/encode-number/ Given a non-negative integer num, Return its en ...

  3. Function Evaluation

    Author: Leisureeen Time Limit: 100ms Memory Limit: 65535KB Code Size Limit: 16 KB 64-bit integer IO ...

  4. gRPC-拦截器简单使用

    概述 gRPC作为通用RPC框架,内置了拦截器功能.包括服务器端的拦截器和客户端拦截器,使用上大同小异.主要作用是在rpc调用的前后进行额外处理. 从客户端角度讲,可以在请求发起前,截取到请求参数并修 ...

  5. MySQL恩恩怨怨

    数据库基础 Windows安装MySQL Mac安装MySQL Linux安装MySQL MySQL存储引擎概述 MySQL表操作 MySQL支持的数据类型 MySQL表的完整性约束 MySQL记录操 ...

  6. ubuntu 使用阿里云镜像源快速搭建kubernetes 1.15.2集群

    一.概述 搭建k8s集群时,需要访问google,下载相关镜像以及安装软件,非常麻烦. 正好阿里云提供了k8s的更新源,国内用户就可以直接使用了. 二.环境介绍 操作系统 主机名 IP地址 功能 配置 ...

  7. emmet css 缩写

    css 缩写 对于CSS语法,Emmet有许多用于属性的预定义代码段.例如,您可以扩展 m 缩写以获取margin: ;代码段. 要获取 margin: 10px;您可以简单地扩展m10缩写. 需要多 ...

  8. node-red inject节点 debug节点 switch节点

    inject节点: https://blog.csdn.net/geek_monkey/article/details/80737818 debug节点: https://blog.csdn.net/ ...

  9. (转)Python_如何把Python脚本导出为exe程序

    原文地址:https://www.cnblogs.com/robinunix/p/8426832.html 一.pyinstaller简介 Python是一个脚本语言,被解释器解释执行.它的发布方式: ...

  10. 强大的Grafana k8s 插件

    原文参考: https://i4t.com/4152.html 参考:https://blog.csdn.net/mailjoin/article/details/81389700 插件链接:http ...