STM32单片机是如何启动的?
STM32单片机是如何启动的?
STM32中的内存
STM32中的内存包含两块主要区域:flash memory(只读)、static ram memory(SRAM,读写)。其中,flash memory 起始于0x08000000,SRAM起始于0x20000000。flash memory的第一部分存放异常向量表,表中包含了指向各种异常处理程序的指针。比如说,RESET Handler便位于0x08000004的位置,在处理器上电或重启时执行。在0x08000000处存放的是内部栈指针。
STM32的存储器映射如下图所示:

程序执行时,机器代码位于flash区域,变量和运行时栈等易变的内容位于SRAM中。
startup.s
下面看一下start.s的代码,了解下如何定义不同类型的代码。
Stack_Size EQU 0x400 ;定义一个变量Stack_Size,相当于 Stack_Size = 0x400
AREA STACK, NOINIT, READWRITE, ALIGN=3 ;定义一个segment 命名为 STACK
Stack_Mem SPACE Stack_Size ;连续0x400个字节清零
__initial_sp
; <h> Heap Configuration
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Heap_Size EQU 0x200
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
这段代码中主要是定义了两个段(segment),这两个段都是可读写的,涉及到两个汇编指令AREA和SPACE。
AREA
语法:
AREA sectionname{,attr}{,attr}...where: sectionname is the name to give to the section. Sections are independent, named, indivisible chunks of code or data that are manipulated by the linker.
当遇到下一个AREA时,表示该段结束。或者是,碰到END也表示该段结束。
AREA属性:
NOINIT 该数据段无须初始化
READWRITE 可读写
DATA 数据而非指令,默认是可读写的
ALIGN 对齐SPACE
语法:
{label} SPACE expr
The SPACE directive reserves a zeroed block of memory.
保留了一段零初始化的内存
紧接着,定义了一个RESET段,该段只读的数据段,该段主要包含异常向量表。异常向量表的每一个元素都是一个函数地址,CDC表示一个字长的整形数据。向量的第一个元素是栈顶地址,第二个元素是Reset_Handler。
PRESERVE8
THUMB
; 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
DCD NMI_Handler ; NMI Handler
/******后面代码省略********/
定义完向量表之后,又定义了.text段,也就是存放程序代码段,该段也是只读的。
该段定义了向量表中的各个处理程序,每个程序以PROC开始,以ENDP结束。第一个是Reset_Handler处理函数,单片机器动时便是从这里开始执行的。我们可以看到,除了ResetHandler其他的函数都只有一个 "B ."这是一个空的跳转,相当于进了死循环,所以需要在外部定义相应的处理函数。
Reset_Handler函数首先执行函数SystemInit,完成硬件初始化工作,然后执行__main建立C运行环境并从中调到用户定义的main()函数执行。
AREA |.text|, CODE, READONLY
; Reset handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT __main
LDR R0, =SystemInit
BLX R0
LDR R0, =__main
BX R0
ENDP
; Dummy Exception Handlers (infinite loops which can be modified)
NMI_Handler PROC
EXPORT NMI_Handler [WEAK]
B .
ENDP
下载程序到单片机
startup.s汇编程序经过汇编器编译后,产生目标代码,然后通过链接器将各个子程序链接为可执行代码。在链接之前,目标代码中的地址都是相对地址,只有链接之后才能转变为可执行的目标代码。在链接过程中,会确定每一部分代码的地址。这个过程都被IDE封装起来了,所以用户看不到。
链接过程中,不同的段的地址是不一样的,比如可读写的段必须放在SRAM对应的地址中(0x20000000开始),只读的段放到flash中(0x08000000开始)。我们可以在keil开发环境的Linker选项面板中看到读写和只读存放的地址,如下图所示。

下载到单片机时,也是分别制定了RAM和flash的地址,下图所示。

STM32单片机是如何启动的?的更多相关文章
- 关于STM32单片机的IAP实现
基于STM32F103单片机的IAP实现(虽然该篇文章不会详细写出实现细节,但是会从一个全局的角度讲述,实际的实现细节只需根据datasheet即可完成). 一.基础概念 什么是IAP?IAP即在应用 ...
- STM32单片机串口一键下载电路与操作方法详解
STM32三种启动模式对应的存储介质均是芯片内置的,它们是:1)用户闪存 = 芯片内置的Flash.2)SRAM = 芯片内置的RAM区,就是内存啦.3)系统存储器 = 芯片内部一块特定的区域,芯片出 ...
- Linux下开发STM32单片机
一开始学习51单片机就是用的MDK这个IDE软件,IDE软件虽然看起来直观好像更加容易入门(因为有界面看起来很形象),但是实际上IDE却是向我们这些入门人员隐藏了背后真实存在的过程,让我们以为编译就是 ...
- 使用 VSCode 开发调试 STM32 单片机尝试
使用 VSCode 开发调试 STM32 单片机尝试 本文记录基于 Windows + DAP-Link 开发 STM32F103C8T6 的实践过程,其他操作系统或芯片应该也只是大同小异的问题. 注 ...
- 龙邱STM32单片机用J-LINK下载无法被识别的解决方法
问题如下: 按照正常步骤使用keil5给龙邱的stm32下载程序,SWD下载方式提示no cortex-m sw device found,JTAG方式提示no cortex-m device fou ...
- STM32单片机在Keil5下仿真的问题解决及GPIO口初始化、使用
STM32单片机在Keil5下仿真的问题解决及GPIO口初始化.使用 最近看了视频,里面有仿真,可以清楚看到GPIO口的数据变化,也想尝试下,DUG时却出现*** error 65: access v ...
- STM32单片机学习心得——概述
我校的课程真是跟不上时代发展,甚至还在教授8051/8052单片机的内容,于是不甘寂寞的我就自己踏入了STM32单片机的坑-- 首先,我现在大二,刚学完模拟电子技术,还没有学习数字电路技术,于是自学单 ...
- 基于STM32单片机光学指纹识别模块(FPM10A)全教程(基于C语言)
本文转载,其来源在参考中:1,稍加修改,因为近期使用到这个模块,故而加以整理! 1.平台 首先我使用的是 奋斗 STM32 开发板 MINI板 基于STM32单片机光学指纹识别模块(FPM10A)全教 ...
- 51单片机和STM32单片机区别在那里
大部分朋友可能都知道51单片机和stm32单片机也知道一般入门会先学习51单片机在学习stm32单片机会简单一些,但是对于51单片机和stm32单片机的具体区别却不知道了,有些人觉得没必要,但是我个 ...
随机推荐
- Intermediate_JVM 20180306 : 运行时数据区域
Java比起C++一个很大的进步就在于Java不用再手动控制指针的delete与free,统一交由JVM管理,但也正因为如此,一旦出现内存溢出异常,不了解JVM,那么排查问题将会变成一项艰难的工作. ...
- SSH整合(一)
一.ssh原始整合方式 不需要任何整合包,就是简单的将三个框架集合到一起 hibernate 导入jar包: hibernate-release-5.0.7.Fin ...
- 可能是catalan数吧
What's the number of distinct BSTs containing nodes {1, 2, 3 ,4}? 包含节点{1,2,3,4}的不同二叉搜索树有多少棵? int Num ...
- HDU1398 Square Coins(生成函数)
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission( ...
- git 码云 使用记录
使用了码云的私有仓库. 一.首先下载安装git 安装完成后,在开始菜单里找到“Git”->“Git Bash”,蹦出一个类似命令行窗口的东西,就说明Git安装成功! 二.创建版本库 什么是版本库 ...
- linux系统基础之---RAID(基于centos7.4 1708)
- Python学习 :装饰器
装饰器(函数) 装饰器作为一个函数,可以为其他函数在不修改原函数代码的前提下添加新的功能 装饰器的返回值是一个函数对象.它经常用于有切面需求的场景,比如:插入日志.性能测试.事务处理.缓存.权限校验等 ...
- 广州Uber优步司机奖励政策(1月4日~1月10日)
滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...
- hive中 udf,udaf,udtf
1.hive中基本操作: DDL,DML 2.hive中函数 User-Defined Functions : UDF(用户自定义函数,简称JDF函数)UDF: 一进一出 upper lower ...
- ROS Twist和Odometry消息类型使用(Python)
消息类型: 1. Twist - 线速度角速度 通常被用于发送到/cmd_vel话题,被base controller节点监听,控制机器人运动 geometry_msgs/Twist geometry ...